diff --git a/contracts/ModuleRegistry.sol b/contracts/ModuleRegistry.sol index ec204914a..59a02af74 100644 --- a/contracts/ModuleRegistry.sol +++ b/contracts/ModuleRegistry.sol @@ -35,6 +35,14 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { */ + bytes32 constant INITIALIZE = 0x9ef7257c3339b099aacf96e55122ee78fb65a36bd2a6c19249882be9c98633bf; //keccak256("initialised") + bytes32 constant POLYTOKEN = 0xacf8fbd51bb4b83ba426cdb12f63be74db97c412515797993d2a385542e311d7; //keccak256("polyToken") + bytes32 constant PAUSED = 0xee35723ac350a69d2a92d3703f17439cbaadf2f093a21ba5bf5f1a53eb2a14d9; //keccak256("paused") + bytes32 constant OWNER = 0x02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c0; //keccak256("owner") + bytes32 constant POLYMATHREGISTRY = 0x90eeab7c36075577c7cc5ff366e389fefa8a18289b949bab3529ab4471139d4d; //keccak256("polymathRegistry") + bytes32 constant FEATURE_REGISTRY = 0xed9ca06607835ad25ecacbcb97f2bc414d4a51ecf391b5ae42f15991227ab146; //keccak256("featureRegistry") + bytes32 constant SECURITY_TOKEN_REGISTRY = 0x12ada4f7ee6c2b7b933330be61fefa007a1f497dc8df1b349b48071a958d7a81; //keccak256("securityTokenRegistry") + /////////// // Events ////////// @@ -105,12 +113,12 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { } function initialize(address _polymathRegistry, address _owner) external payable { - require(!getBoolValue(Encoder.getKey("initialised")), "already initialized"); + require(!getBoolValue(INITIALIZE), "already initialized"); require(_owner != address(0) && _polymathRegistry != address(0), "0x address is invalid"); - set(Encoder.getKey("polymathRegistry"), _polymathRegistry); - set(Encoder.getKey("owner"), _owner); - set(Encoder.getKey("paused"), false); - set(Encoder.getKey("initialised"), true); + set(POLYMATHREGISTRY, _polymathRegistry); + set(OWNER, _owner); + set(PAUSED, false); + set(INITIALIZE, true); } /** @@ -122,7 +130,7 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { * @param _isUpgrade whether or not the function is being called as a result of an upgrade */ function useModule(address _moduleFactory, bool _isUpgrade) external { - if (IFeatureRegistry(getAddressValue(Encoder.getKey("featureRegistry"))).getFeatureStatus("customModulesAllowed")) { + if (IFeatureRegistry(getAddressValue(FEATURE_REGISTRY)).getFeatureStatus("customModulesAllowed")) { require( getBoolValue(Encoder.getKey("verified", _moduleFactory)) || IOwnable(_moduleFactory).owner() == IOwnable(msg.sender).owner(), "ModuleFactory must be verified or SecurityToken owner must be ModuleFactory owner" @@ -132,7 +140,7 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { } // This if statement is required to be able to add modules from the STFactory contract during deployment // before the token has been registered to the STR. - if (ISecurityTokenRegistry(getAddressValue(Encoder.getKey("securityTokenRegistry"))).isSecurityToken(msg.sender)) { + if (ISecurityTokenRegistry(getAddressValue(SECURITY_TOKEN_REGISTRY)).isSecurityToken(msg.sender)) { require(isCompatibleModule(_moduleFactory, msg.sender), "Incompatible versions"); if (!_isUpgrade) { pushArray(Encoder.getKey("reputation", _moduleFactory), msg.sender); @@ -161,7 +169,7 @@ 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(getAddressValue(Encoder.getKey("featureRegistry"))).getFeatureStatus("customModulesAllowed")) { + if (IFeatureRegistry(getAddressValue(FEATURE_REGISTRY)).getFeatureStatus("customModulesAllowed")) { require( msg.sender == IOwnable(_moduleFactory).owner() || msg.sender == owner(), "msg.sender must be the Module Factory owner or registry curator" @@ -337,7 +345,7 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { function getModulesByTypeAndToken(uint8 _moduleType, address _securityToken) public view returns(address[] memory) { address[] memory _addressList = getArrayAddress(Encoder.getKey("moduleList", uint256(_moduleType))); uint256 _len = _addressList.length; - bool _isCustomModuleAllowed = IFeatureRegistry(getAddressValue(Encoder.getKey("featureRegistry"))).getFeatureStatus( + bool _isCustomModuleAllowed = IFeatureRegistry(getAddressValue(FEATURE_REGISTRY)).getFeatureStatus( "customModulesAllowed" ); uint256 counter = 0; @@ -387,7 +395,7 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { * @notice Called by the owner to pause, triggers stopped state */ function pause() external whenNotPaused onlyOwner { - set(Encoder.getKey("paused"), true); + set(PAUSED, true); /*solium-disable-next-line security/no-block-members*/ emit Pause(msg.sender); } @@ -396,7 +404,7 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { * @notice Called by the owner to unpause, returns to normal state */ function unpause() external whenPaused onlyOwner { - set(Encoder.getKey("paused"), false); + set(PAUSED, false); /*solium-disable-next-line security/no-block-members*/ emit Unpause(msg.sender); } @@ -405,10 +413,10 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { * @notice Stores the contract addresses of other key contracts from the PolymathRegistry */ function updateFromRegistry() external onlyOwner { - address _polymathRegistry = getAddressValue(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")); + address _polymathRegistry = getAddressValue(POLYMATHREGISTRY); + set(SECURITY_TOKEN_REGISTRY, IPolymathRegistry(_polymathRegistry).getAddress("SecurityTokenRegistry")); + set(FEATURE_REGISTRY, IPolymathRegistry(_polymathRegistry).getAddress("FeatureRegistry")); + set(POLYTOKEN, IPolymathRegistry(_polymathRegistry).getAddress("PolyToken")); } /** @@ -418,7 +426,7 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { function transferOwnership(address _newOwner) external onlyOwner { require(_newOwner != address(0), "Invalid address"); emit OwnershipTransferred(owner(), _newOwner); - set(Encoder.getKey("owner"), _newOwner); + set(OWNER, _newOwner); } /** @@ -426,7 +434,7 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { * @return address owner */ function owner() public view returns(address) { - return getAddressValue(Encoder.getKey("owner")); + return getAddressValue(OWNER); } /** @@ -434,6 +442,6 @@ contract ModuleRegistry is IModuleRegistry, EternalStorage { * @return bool */ function isPaused() public view returns(bool) { - return getBoolValue(Encoder.getKey("paused")); + return getBoolValue(PAUSED); } } diff --git a/contracts/RegistryUpdater.sol b/contracts/RegistryUpdater.sol deleted file mode 100644 index 70e6c6849..000000000 --- a/contracts/RegistryUpdater.sol +++ /dev/null @@ -1,25 +0,0 @@ -pragma solidity ^0.5.0; - -import "openzeppelin-solidity/contracts/ownership/Ownable.sol"; -import "./PolymathRegistry.sol"; - -contract RegistryUpdater is Ownable { - address public polymathRegistry; - address public moduleRegistry; - address public securityTokenRegistry; - address public featureRegistry; - address public polyToken; - - constructor(address _polymathRegistry) public { - require(_polymathRegistry != address(0), "Invalid address"); - polymathRegistry = _polymathRegistry; - } - - function updateFromRegistry() public onlyOwner { - moduleRegistry = PolymathRegistry(polymathRegistry).getAddress("ModuleRegistry"); - securityTokenRegistry = PolymathRegistry(polymathRegistry).getAddress("SecurityTokenRegistry"); - featureRegistry = PolymathRegistry(polymathRegistry).getAddress("FeatureRegistry"); - polyToken = PolymathRegistry(polymathRegistry).getAddress("PolyToken"); - } - -} diff --git a/contracts/SecurityTokenRegistry.sol b/contracts/SecurityTokenRegistry.sol index b9fd76ff2..533a40c63 100644 --- a/contracts/SecurityTokenRegistry.sol +++ b/contracts/SecurityTokenRegistry.sol @@ -67,16 +67,18 @@ contract SecurityTokenRegistry is EternalStorage, Proxy { using SafeMath for uint256; - bytes32 constant INITIALIZE = 0x9ef7257c3339b099aacf96e55122ee78fb65a36bd2a6c19249882be9c98633bf; - bytes32 constant POLYTOKEN = 0xacf8fbd51bb4b83ba426cdb12f63be74db97c412515797993d2a385542e311d7; - bytes32 constant STLAUNCHFEE = 0xd677304bb45536bb7fdfa6b9e47a3c58fe413f9e8f01474b0a4b9c6e0275baf2; - bytes32 constant TICKERREGFEE = 0x2fcc69711628630fb5a42566c68bd1092bc4aa26826736293969fddcd11cb2d2; - bytes32 constant EXPIRYLIMIT = 0x604268e9a73dfd777dcecb8a614493dd65c638bad2f5e7d709d378bd2fb0baee; - bytes32 constant PAUSED = 0xee35723ac350a69d2a92d3703f17439cbaadf2f093a21ba5bf5f1a53eb2a14d9; - bytes32 constant OWNER = 0x02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c0; - bytes32 constant POLYMATHREGISTRY = 0x90eeab7c36075577c7cc5ff366e389fefa8a18289b949bab3529ab4471139d4d; - bytes32 constant STRGETTER = 0x982f24b3bd80807ec3cb227ba152e15c07d66855fa8ae6ca536e689205c0e2e9; + bytes32 constant INITIALIZE = 0x9ef7257c3339b099aacf96e55122ee78fb65a36bd2a6c19249882be9c98633bf; //keccak256("initialised") + bytes32 constant POLYTOKEN = 0xacf8fbd51bb4b83ba426cdb12f63be74db97c412515797993d2a385542e311d7; //keccak256("polyToken") + bytes32 constant STLAUNCHFEE = 0xd677304bb45536bb7fdfa6b9e47a3c58fe413f9e8f01474b0a4b9c6e0275baf2; //keccak256("stLaunchFee") + bytes32 constant TICKERREGFEE = 0x2fcc69711628630fb5a42566c68bd1092bc4aa26826736293969fddcd11cb2d2; //keccak256("tickerRegFee") + bytes32 constant EXPIRYLIMIT = 0x604268e9a73dfd777dcecb8a614493dd65c638bad2f5e7d709d378bd2fb0baee; //keccak256("expiryLimit") + bytes32 constant PAUSED = 0xee35723ac350a69d2a92d3703f17439cbaadf2f093a21ba5bf5f1a53eb2a14d9; //keccak256("paused") + bytes32 constant OWNER = 0x02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c0; //keccak256("owner") + bytes32 constant POLYMATHREGISTRY = 0x90eeab7c36075577c7cc5ff366e389fefa8a18289b949bab3529ab4471139d4d; //keccak256("polymathRegistry") + bytes32 constant STRGETTER = 0x982f24b3bd80807ec3cb227ba152e15c07d66855fa8ae6ca536e689205c0e2e9; //keccak256("STRGetter") bytes32 constant IS_FEE_IN_POLY = 0x7152e5426955da44af11ecd67fec5e2a3ba747be974678842afa9394b9a075b6; //keccak256("IS_FEE_IN_POLY") + bytes32 constant ACTIVE_USERS = 0x425619ce6ba8e9f80f17c0ef298b6557e321d70d7aeff2e74dd157bd87177a9e; //keccak256("activeUsers") + bytes32 constant LATEST_VERSION = 0x4c63b69b9117452b9f11af62077d0cda875fb4e2dbe07ad6f31f728de6926230; //keccak256("latestVersion") string constant POLY_ORACLE = "StablePolyUsdOracle"; @@ -196,7 +198,6 @@ contract SecurityTokenRegistry is EternalStorage, Proxy { address _getterContract ) public - payable { require(!getBoolValue(INITIALIZE),"Initialized"); require( @@ -264,7 +265,7 @@ contract SecurityTokenRegistry is EternalStorage, Proxy { } function _implementation() internal view returns(address) { - return getAddressValue(Encoder.getKey("STRGetter")); + return getAddressValue(STRGETTER); } ///////////////////////////// @@ -422,7 +423,7 @@ contract SecurityTokenRegistry is EternalStorage, Proxy { set(Encoder.getKey("tickerIndex", _ticker), length); bytes32 seenKey = Encoder.getKey("seenUsers", _owner); if (!getBoolValue(seenKey)) { - pushArray(Encoder.getKey("activeUsers"), _owner); + pushArray(ACTIVE_USERS, _owner); set(seenKey, true); } } @@ -528,7 +529,7 @@ contract SecurityTokenRegistry is EternalStorage, Proxy { require(bytes(_name).length > 0 && bytes(_ticker).length > 0, "Bad ticker"); require(_treasuryWallet != address(0), "0x0 not allowed"); if (_protocolVersion == 0) { - protocolVersion = getUintValue(Encoder.getKey("latestVersion")); + protocolVersion = getUintValue(LATEST_VERSION); } require(protocolVersion != uint256(0), "Invalid version"); string memory ticker = Util.upper(_ticker); @@ -572,7 +573,7 @@ contract SecurityTokenRegistry is EternalStorage, Proxy { address stOwner = IOwnable(st).owner(); require(msg.sender == stOwner, "Unauthroized"); require(ISecurityToken(st).transfersFrozen(), "Transfers not frozen"); - uint256 protocolVersion = getUintValue(Encoder.getKey("latestVersion")); + uint256 protocolVersion = getUintValue(LATEST_VERSION); address newSecurityTokenAddress = _deployToken(_name, ticker, _tokenDetails, stOwner, _divisible, _treasuryWallet, protocolVersion); emit SecurityTokenRefreshed( @@ -777,7 +778,6 @@ contract SecurityTokenRegistry is EternalStorage, Proxy { function _setProtocolFactory(address _STFactoryAddress, uint8 _major, uint8 _minor, uint8 _patch) internal { require(_STFactoryAddress != address(0), "Bad address"); uint24 _packedVersion = VersionUtils.pack(_major, _minor, _patch); - //set(Encoder.getKey("latestVersion"), uint256(_packedVersion)); set(Encoder.getKey("protocolVersionST", uint256(_packedVersion)), _STFactoryAddress); emit ProtocolFactorySet(_STFactoryAddress, _major, _minor, _patch); } @@ -790,7 +790,7 @@ contract SecurityTokenRegistry is EternalStorage, Proxy { */ function removeProtocolFactory(uint8 _major, uint8 _minor, uint8 _patch) public onlyOwner { uint24 _packedVersion = VersionUtils.pack(_major, _minor, _patch); - require(getUintValue(Encoder.getKey("latestVersion")) != _packedVersion, "Cannot remove latestVersion"); + require(getUintValue(LATEST_VERSION) != _packedVersion, "Cannot remove latestVersion"); emit ProtocolFactoryRemoved(getAddressValue(Encoder.getKey("protocolVersionST", _packedVersion)), _major, _minor, _patch); set(Encoder.getKey("protocolVersionST", uint256(_packedVersion)), address(0)); } @@ -810,7 +810,7 @@ contract SecurityTokenRegistry is EternalStorage, Proxy { function _setLatestVersion(uint8 _major, uint8 _minor, uint8 _patch) internal { uint24 _packedVersion = VersionUtils.pack(_major, _minor, _patch); require(getAddressValue(Encoder.getKey("protocolVersionST", _packedVersion)) != address(0), "No factory"); - set(Encoder.getKey("latestVersion"), uint256(_packedVersion)); + set(LATEST_VERSION, uint256(_packedVersion)); emit LatestVersionSet(_major, _minor, _patch); } diff --git a/contracts/datastore/DataStore.sol b/contracts/datastore/DataStore.sol index 1d12c13d8..50a397838 100644 --- a/contracts/datastore/DataStore.sol +++ b/contracts/datastore/DataStore.sol @@ -164,28 +164,28 @@ contract DataStore is DataStoreStorage, IDataStore { * @param _keys Array of keys to identify the data * @param _data Array of data to be stored against the respective keys */ - function setUint256Multi(bytes32[] calldata _keys, uint256[] calldata _data) external validArrayLength(_keys.length, _data.length) { + function setUint256Multi(bytes32[] memory _keys, uint256[] memory _data) public validArrayLength(_keys.length, _data.length) { _isAuthorized(); for (uint256 i = 0; i < _keys.length; i++) { _setData(_keys[i], _data[i], false); } } - function setBytes32Multi(bytes32[] calldata _keys, bytes32[] calldata _data) external validArrayLength(_keys.length, _data.length) { + function setBytes32Multi(bytes32[] memory _keys, bytes32[] memory _data) public validArrayLength(_keys.length, _data.length) { _isAuthorized(); for (uint256 i = 0; i < _keys.length; i++) { _setData(_keys[i], _data[i], false); } } - function setAddressMulti(bytes32[] calldata _keys, address[] calldata _data) external validArrayLength(_keys.length, _data.length) { + function setAddressMulti(bytes32[] memory _keys, address[] memory _data) public validArrayLength(_keys.length, _data.length) { _isAuthorized(); for (uint256 i = 0; i < _keys.length; i++) { _setData(_keys[i], _data[i], false); } } - function setBoolMulti(bytes32[] calldata _keys, bool[] calldata _data) external validArrayLength(_keys.length, _data.length) { + function setBoolMulti(bytes32[] memory _keys, bool[] memory _data) public validArrayLength(_keys.length, _data.length) { _isAuthorized(); for (uint256 i = 0; i < _keys.length; i++) { _setData(_keys[i], _data[i], false); @@ -197,28 +197,28 @@ contract DataStore is DataStoreStorage, IDataStore { * @param _keys Array of keys to identify the data * @param _data Array of data to be inserted in arrays of the respective keys */ - function insertUint256Multi(bytes32[] calldata _keys, uint256[] calldata _data) external validArrayLength(_keys.length, _data.length) { + function insertUint256Multi(bytes32[] memory _keys, uint256[] memory _data) public validArrayLength(_keys.length, _data.length) { _isAuthorized(); for (uint256 i = 0; i < _keys.length; i++) { _setData(_keys[i], _data[i], true); } } - function insertBytes32Multi(bytes32[] calldata _keys, bytes32[] calldata _data) external validArrayLength(_keys.length, _data.length) { + function insertBytes32Multi(bytes32[] memory _keys, bytes32[] memory _data) public validArrayLength(_keys.length, _data.length) { _isAuthorized(); for (uint256 i = 0; i < _keys.length; i++) { _setData(_keys[i], _data[i], true); } } - function insertAddressMulti(bytes32[] calldata _keys, address[] calldata _data) external validArrayLength(_keys.length, _data.length) { + function insertAddressMulti(bytes32[] memory _keys, address[] memory _data) public validArrayLength(_keys.length, _data.length) { _isAuthorized(); for (uint256 i = 0; i < _keys.length; i++) { _setData(_keys[i], _data[i], true); } } - function insertBoolMulti(bytes32[] calldata _keys, bool[] calldata _data) external validArrayLength(_keys.length, _data.length) { + function insertBoolMulti(bytes32[] memory _keys, bool[] memory _data) public validArrayLength(_keys.length, _data.length) { _isAuthorized(); for (uint256 i = 0; i < _keys.length; i++) { _setData(_keys[i], _data[i], true); @@ -297,7 +297,7 @@ contract DataStore is DataStoreStorage, IDataStore { return boolArrayData[_key][_index]; } - function getUint256ArrayElements(bytes32 _key, uint256 _startIndex, uint256 _endIndex) external view returns(uint256[] memory array) { + function getUint256ArrayElements(bytes32 _key, uint256 _startIndex, uint256 _endIndex) public view returns(uint256[] memory array) { uint256 size = uintArrayData[_key].length; if (_endIndex >= size) { size = size - _startIndex; @@ -309,7 +309,7 @@ contract DataStore is DataStoreStorage, IDataStore { array[i] = uintArrayData[_key][i + _startIndex]; } - function getBytes32ArrayElements(bytes32 _key, uint256 _startIndex, uint256 _endIndex) external view returns(bytes32[] memory array) { + function getBytes32ArrayElements(bytes32 _key, uint256 _startIndex, uint256 _endIndex) public view returns(bytes32[] memory array) { uint256 size = bytes32ArrayData[_key].length; if (_endIndex >= size) { size = size - _startIndex; @@ -321,7 +321,7 @@ contract DataStore is DataStoreStorage, IDataStore { array[i] = bytes32ArrayData[_key][i + _startIndex]; } - function getAddressArrayElements(bytes32 _key, uint256 _startIndex, uint256 _endIndex) external view returns(address[] memory array) { + function getAddressArrayElements(bytes32 _key, uint256 _startIndex, uint256 _endIndex) public view returns(address[] memory array) { uint256 size = addressArrayData[_key].length; if (_endIndex >= size) { size = size - _startIndex; @@ -333,7 +333,7 @@ contract DataStore is DataStoreStorage, IDataStore { array[i] = addressArrayData[_key][i + _startIndex]; } - function getBoolArrayElements(bytes32 _key, uint256 _startIndex, uint256 _endIndex) external view returns(bool[] memory array) { + function getBoolArrayElements(bytes32 _key, uint256 _startIndex, uint256 _endIndex) public view returns(bool[] memory array) { uint256 size = boolArrayData[_key].length; if (_endIndex >= size) { size = size - _startIndex; diff --git a/contracts/interfaces/ISecurityToken.sol b/contracts/interfaces/ISecurityToken.sol index c3ccef5bc..7fba2be46 100644 --- a/contracts/interfaces/ISecurityToken.sol +++ b/contracts/interfaces/ISecurityToken.sol @@ -539,6 +539,12 @@ interface ISecurityToken { */ function granularity() external view returns(uint256); + /** + * @notice Provides the address of the polymathRegistry + * @return address + */ + function polymathRegistry() external view returns(address); + /** * @notice Upgrades a module attached to the SecurityToken * @param _module address of module to archive diff --git a/contracts/libraries/DecimalMath.sol b/contracts/libraries/DecimalMath.sol index ab942bad2..92abcc7de 100644 --- a/contracts/libraries/DecimalMath.sol +++ b/contracts/libraries/DecimalMath.sol @@ -5,12 +5,14 @@ import "openzeppelin-solidity/contracts/math/SafeMath.sol"; library DecimalMath { using SafeMath for uint256; + uint256 internal constant e18 = uint256(10) ** uint256(18); + /** * @notice This function multiplies two decimals represented as (decimal * 10**DECIMALS) * @return uint256 Result of multiplication represented as (decimal * 10**DECIMALS) */ function mul(uint256 x, uint256 y) internal pure returns(uint256 z) { - z = SafeMath.add(SafeMath.mul(x, y), (10 ** 18) / 2) / (10 ** 18); + z = SafeMath.add(SafeMath.mul(x, y), (e18) / 2) / (e18); } /** @@ -18,7 +20,7 @@ library DecimalMath { * @return uint256 Result of division represented as (decimal * 10**DECIMALS) */ function div(uint256 x, uint256 y) internal pure returns(uint256 z) { - z = SafeMath.add(SafeMath.mul(x, (10 ** 18)), y / 2) / y; + z = SafeMath.add(SafeMath.mul(x, (e18)), y / 2) / y; } } diff --git a/contracts/libraries/TokenLib.sol b/contracts/libraries/TokenLib.sol index e627aea74..e0f318fa9 100644 --- a/contracts/libraries/TokenLib.sol +++ b/contracts/libraries/TokenLib.sol @@ -364,7 +364,7 @@ library TokenLib { bytes32 name, string memory uri, bytes32 documentHash - ) + ) public { require(name != bytes32(0), "Bad name"); @@ -388,7 +388,7 @@ library TokenLib { mapping(bytes32 => uint256) storage docIndexes, bytes32 name ) - public + public { require(document[name].lastModified != uint256(0), "Not existed"); uint256 index = docIndexes[name] - 1; @@ -460,24 +460,25 @@ library TokenLib { bytes32 appCode, address to, uint256 value, - uint256 balanceOfFrom, - uint256 balanceOfTo - ) + uint256 balanceOfFrom + ) public - pure - returns (bool, byte, bytes32) + pure + returns (bool, byte, bytes32) { if (!success) return (false, 0x50, appCode); - else if (balanceOfFrom < value) + if (balanceOfFrom < value) return (false, 0x52, bytes32(0)); - else if (to == address(0)) + if (to == address(0)) return (false, 0x57, bytes32(0)); - else if (!KindMath.checkAdd(balanceOfTo, value)) - return (false, 0x50, bytes32(0)); + // Balance overflow can never happen due to totalsupply being a uint256 as well + // else if (!KindMath.checkAdd(balanceOf(_to), _value)) + // return (false, 0x50, bytes32(0)); + return (true, 0x51, bytes32(0)); } diff --git a/contracts/mocks/MockSecurityTokenLogic.sol b/contracts/mocks/MockSecurityTokenLogic.sol index b87b75fad..814ab7bbb 100644 --- a/contracts/mocks/MockSecurityTokenLogic.sol +++ b/contracts/mocks/MockSecurityTokenLogic.sol @@ -22,8 +22,6 @@ contract MockSecurityTokenLogic is SecurityToken { * @dev Can only be called once */ function upgrade(address _getterDelegate, uint256 _upgrade) external { - require(msg.sender == address(this)); - //Expected to be called atomically with the proxy being created getterDelegate = _getterDelegate; //securityTokenVersion = SemanticVersion(3, 1, 0); emit UpgradeEvent(_upgrade); @@ -33,4 +31,18 @@ contract MockSecurityTokenLogic is SecurityToken { emit UpgradeEvent(_upgrade); } + //To reduce bytecode size + function addModuleWithLabel( + address /* _moduleFactory */, + bytes memory /* _data */, + uint256 /* _maxCost */, + uint256 /* _budget */, + bytes32 /* _label */, + bool /* _archived */ + ) + public + { + emit UpgradeEvent(0); + } + } diff --git a/contracts/mocks/SecurityTokenMock.sol b/contracts/mocks/SecurityTokenMock.sol index 1aaf56864..9f3b6a1d2 100644 --- a/contracts/mocks/SecurityTokenMock.sol +++ b/contracts/mocks/SecurityTokenMock.sol @@ -13,4 +13,4 @@ contract SecurityTokenMock is SecurityToken { super.initialize(_getterDelegate); securityTokenVersion = SemanticVersion(2, 2, 0); } -} \ No newline at end of file +} diff --git a/contracts/modules/Checkpoint/DividendCheckpoint.sol b/contracts/modules/Checkpoint/DividendCheckpoint.sol index 591aed22a..ee22e1836 100644 --- a/contracts/modules/Checkpoint/DividendCheckpoint.sol +++ b/contracts/modules/Checkpoint/DividendCheckpoint.sol @@ -19,6 +19,7 @@ import "openzeppelin-solidity/contracts/math/Math.sol"; */ contract DividendCheckpoint is DividendCheckpointStorage, ICheckpoint, Module { using SafeMath for uint256; + uint256 internal constant e18 = uint256(10) ** uint256(18); event SetDefaultExcludedAddresses(address[] _excluded); event SetWithholding(address[] _investors, uint256[] _withholding); @@ -123,7 +124,7 @@ contract DividendCheckpoint is DividendCheckpointStorage, ICheckpoint, Module { /*solium-disable-next-line security/no-block-members*/ emit SetWithholding(_investors, _withholding); for (uint256 i = 0; i < _investors.length; i++) { - require(_withholding[i] <= 10 ** 18, "Incorrect withholding tax"); + require(_withholding[i] <= e18, "Incorrect withholding tax"); withholdingTax[_investors[i]] = _withholding[i]; } } @@ -134,7 +135,7 @@ contract DividendCheckpoint is DividendCheckpointStorage, ICheckpoint, Module { * @param _withholding Withholding tax for all investors (multiplied by 10**16) */ function setWithholdingFixed(address[] memory _investors, uint256 _withholding) public withPerm(ADMIN) { - require(_withholding <= 10 ** 18, "Incorrect withholding tax"); + require(_withholding <= e18, "Incorrect withholding tax"); /*solium-disable-next-line security/no-block-members*/ emit SetWithholdingFixed(_investors, _withholding); for (uint256 i = 0; i < _investors.length; i++) { @@ -232,7 +233,7 @@ contract DividendCheckpoint is DividendCheckpointStorage, ICheckpoint, Module { } 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)); + uint256 withheld = claim.mul(withholdingTax[_payee]).div(e18); return (claim, withheld); } diff --git a/contracts/modules/Checkpoint/ERC20/ERC20DividendCheckpoint.sol b/contracts/modules/Checkpoint/ERC20/ERC20DividendCheckpoint.sol index b4120122d..66756aff5 100644 --- a/contracts/modules/Checkpoint/ERC20/ERC20DividendCheckpoint.sol +++ b/contracts/modules/Checkpoint/ERC20/ERC20DividendCheckpoint.sol @@ -162,7 +162,7 @@ contract ERC20DividendCheckpoint is ERC20DividendCheckpointStorage, DividendChec require(_token != address(0), "Invalid token"); require(_checkpointId <= securityTokenInstance.currentCheckpointId(), "Invalid checkpoint"); require(IERC20(_token).transferFrom(msg.sender, address(this), _amount), "insufficent allowance"); - require(_name[0] != 0); + require(_name != bytes32(0)); uint256 dividendIndex = dividends.length; uint256 currentSupply = securityTokenInstance.totalSupplyAt(_checkpointId); require(currentSupply > 0, "Invalid supply"); diff --git a/contracts/modules/Checkpoint/Ether/EtherDividendCheckpoint.sol b/contracts/modules/Checkpoint/Ether/EtherDividendCheckpoint.sol index 6478f3e55..520e390d5 100644 --- a/contracts/modules/Checkpoint/Ether/EtherDividendCheckpoint.sol +++ b/contracts/modules/Checkpoint/Ether/EtherDividendCheckpoint.sol @@ -128,7 +128,7 @@ contract EtherDividendCheckpoint is DividendCheckpoint { require(_expiry > now, "Expiry is in the past"); require(msg.value > 0, "No dividend sent"); require(_checkpointId <= ISecurityToken(securityToken).currentCheckpointId()); - require(_name[0] != 0); + require(_name[0] != bytes32(0)); uint256 dividendIndex = dividends.length; uint256 currentSupply = ISecurityToken(securityToken).totalSupplyAt(_checkpointId); require(currentSupply > 0, "Invalid supply"); diff --git a/contracts/modules/PermissionManager/GeneralPermissionManager.sol b/contracts/modules/PermissionManager/GeneralPermissionManager.sol index 2ed455c3a..c6b93cb32 100644 --- a/contracts/modules/PermissionManager/GeneralPermissionManager.sol +++ b/contracts/modules/PermissionManager/GeneralPermissionManager.sol @@ -62,10 +62,11 @@ contract GeneralPermissionManager is GeneralPermissionManagerStorage, IPermissio */ function deleteDelegate(address _delegate) external withPerm(ADMIN) { require(delegateDetails[_delegate] != bytes32(0), "delegate does not exist"); - for (uint256 i = 0; i < allDelegates.length; i++) { + uint256 delegateLen = allDelegates.length; + for (uint256 i = 0; i < delegateLen; i++) { if (allDelegates[i] == _delegate) { - allDelegates[i] = allDelegates[allDelegates.length - 1]; - allDelegates.length = allDelegates.length - 1; + allDelegates[i] = allDelegates[delegateLen - 1]; + allDelegates.length--; } } delete delegateDetails[_delegate]; @@ -107,17 +108,16 @@ contract GeneralPermissionManager is GeneralPermissionManagerStorage, IPermissio */ function changePermissionMulti( address _delegate, - address[] calldata _modules, - bytes32[] calldata _perms, - bool[] calldata _valids + address[] memory _modules, + bytes32[] memory _perms, + bool[] memory _valids ) - external + public withPerm(ADMIN) { 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"); + require(_modules.length == _perms.length && _valids.length == _perms.length, "Array length mismatch"); for (uint256 i = 0; i < _perms.length; i++) { _changePermission(_delegate, _modules[i], _perms[i], _valids[i]); } diff --git a/contracts/modules/STO/USDTiered/USDTieredSTO.sol b/contracts/modules/STO/USDTiered/USDTieredSTO.sol index 6a724270d..67b2fc6f1 100644 --- a/contracts/modules/STO/USDTiered/USDTieredSTO.sol +++ b/contracts/modules/STO/USDTiered/USDTieredSTO.sol @@ -1,8 +1,8 @@ pragma solidity ^0.5.0; import "../STO.sol"; +import "../../../interfaces/IPolymathRegistry.sol"; import "../../../interfaces/IOracle.sol"; -import "../../../RegistryUpdater.sol"; import "../../../libraries/DecimalMath.sol"; import "openzeppelin-solidity/contracts/math/SafeMath.sol"; import "./USDTieredSTOStorage.sol"; @@ -758,7 +758,7 @@ contract USDTieredSTO is USDTieredSTOStorage, STO { } function _getOracle(bytes32 _currency, bytes32 _denominatedCurrency) internal view returns(address) { - return PolymathRegistry(RegistryUpdater(securityToken).polymathRegistry()).getAddress(oracleKeys[_currency][_denominatedCurrency]); + return IPolymathRegistry(ISecurityToken(securityToken).polymathRegistry()).getAddress(oracleKeys[_currency][_denominatedCurrency]); } } diff --git a/contracts/modules/TransferManager/CTM/CountTransferManager.sol b/contracts/modules/TransferManager/CTM/CountTransferManager.sol index b32a82ecd..ab3e3d743 100644 --- a/contracts/modules/TransferManager/CTM/CountTransferManager.sol +++ b/contracts/modules/TransferManager/CTM/CountTransferManager.sol @@ -28,12 +28,12 @@ contract CountTransferManager is CountTransferManagerStorage, TransferManager { address _from, address _to, uint256 _amount, - bytes calldata _data + bytes calldata /*_data*/ ) external returns(Result) { - (Result success,) = verifyTransfer(_from, _to, _amount, _data); + (Result success, ) = _verifyTransfer(_from, _to, _amount); return success; } @@ -52,6 +52,18 @@ contract CountTransferManager is CountTransferManagerStorage, TransferManager { public view returns(Result, bytes32) + { + return _verifyTransfer(_from, _to, _amount); + } + + function _verifyTransfer( + address _from, + address _to, + uint256 _amount + ) + internal + view + returns(Result, bytes32) { if (!paused) { if (maxHolderCount < ISecurityToken(securityToken).holderCount()) { diff --git a/contracts/modules/TransferManager/GTM/GeneralTransferManager.sol b/contracts/modules/TransferManager/GTM/GeneralTransferManager.sol index 952b518f8..874e47263 100644 --- a/contracts/modules/TransferManager/GTM/GeneralTransferManager.sol +++ b/contracts/modules/TransferManager/GTM/GeneralTransferManager.sol @@ -40,7 +40,7 @@ contract GeneralTransferManager is GeneralTransferManagerStorage, TransferManage ); event ModifyTransferRequirements( - uint256 indexed _transferType, + TransferType indexed _transferType, bool _fromValidKYC, bool _toValidKYC, bool _fromRestricted, @@ -102,7 +102,7 @@ contract GeneralTransferManager is GeneralTransferManagerStorage, TransferManage function executeTransfer( address _from, address _to, - uint256 _amount, + uint256 /*_amount*/, bytes calldata _data ) external returns(Result) { if (_data.length > 32) { @@ -115,7 +115,7 @@ contract GeneralTransferManager is GeneralTransferManagerStorage, TransferManage if (target == address(this)) _processTransferSignature(nonce, validFrom, validTo, data); } - (Result success,) = verifyTransfer(_from, _to, _amount, _data); + (Result success,) = _verifyTransfer(_from, _to); return success; } @@ -144,6 +144,17 @@ contract GeneralTransferManager is GeneralTransferManagerStorage, TransferManage public view returns(Result, bytes32) + { + return _verifyTransfer(_from, _to); + } + + function _verifyTransfer( + address _from, + address _to + ) + internal + view + returns(Result, bytes32) { if (!paused) { TransferRequirements memory txReq; @@ -153,11 +164,11 @@ contract GeneralTransferManager is GeneralTransferManagerStorage, TransferManage uint64 canReceiveAfter; if (_from == issuanceAddress) { - txReq = transferRequirements[1]; //Issuance + txReq = transferRequirements[uint8(TransferType.ISSUANCE)]; } else if (_to == address(0)) { - txReq = transferRequirements[2]; //Redemption + txReq = transferRequirements[uint8(TransferType.REDEMPTION)]; } else { - txReq = transferRequirements[0]; //General Transfer + txReq = transferRequirements[uint8(TransferType.GENERAL)]; } (canSendAfter, fromExpiry, canReceiveAfter, toExpiry) = _getValuesForTransfer(_from, _to); @@ -186,7 +197,7 @@ contract GeneralTransferManager is GeneralTransferManagerStorage, TransferManage * @param _toRestricted Defines if transfer time restriction is checked for the receiver */ function modifyTransferRequirements( - uint256 _transferType, + TransferType _transferType, bool _fromValidKYC, bool _toValidKYC, bool _fromRestricted, @@ -210,7 +221,7 @@ contract GeneralTransferManager is GeneralTransferManagerStorage, TransferManage * @param _toRestricted Defines if transfer time restriction is checked for the receiver */ function modifyTransferRequirementsMulti( - uint256[] memory _transferTypes, + TransferType[] memory _transferTypes, bool[] memory _fromValidKYC, bool[] memory _toValidKYC, bool[] memory _fromRestricted, @@ -236,14 +247,13 @@ contract GeneralTransferManager is GeneralTransferManagerStorage, TransferManage } function _modifyTransferRequirements( - uint256 _transferType, + TransferType _transferType, bool _fromValidKYC, bool _toValidKYC, bool _fromRestricted, bool _toRestricted ) internal { - require(_transferType < 3, "Invalid TransferType"); - transferRequirements[_transferType] = + transferRequirements[uint8(_transferType)] = TransferRequirements( _fromValidKYC, _toValidKYC, @@ -342,7 +352,7 @@ contract GeneralTransferManager is GeneralTransferManagerStorage, TransferManage IDataStore dataStore = getDataStore(); if (!_isExistingInvestor(_investor, dataStore)) { dataStore.insertAddress(INVESTORSKEY, _investor); - //KYC data can not be present if added is false and hence we can set packed KYC as uint256(1) to set added as true + //KYC data can not be present if _isExistingInvestor is false and hence we can set packed KYC as uint256(1) to set `added` as true dataStore.setUint256(_getKey(WHITELIST, _investor), uint256(1)); } //NB Flags are packed together in a uint256 to save gas. We can have a maximum of 256 flags. @@ -500,13 +510,11 @@ contract GeneralTransferManager is GeneralTransferManagerStorage, TransferManage if (_checkSig(hash, _signature, _nonce)) { for (uint256 i = 0; i < _investor.length; i++) { - require( - uint64(_canSendAfter[i]) == _canSendAfter[i] && + if (uint64(_canSendAfter[i]) == _canSendAfter[i] && uint64(_canReceiveAfter[i]) == _canReceiveAfter[i] && - uint64(_expiryTime[i]) == _expiryTime[i], - "uint64 overflow" - ); - _modifyKYCData(_investor[i], uint64(_canSendAfter[i]), uint64(_canReceiveAfter[i]), uint64(_expiryTime[i])); + uint64(_expiryTime[i]) == _expiryTime[i] + ) + _modifyKYCData(_investor[i], uint64(_canSendAfter[i]), uint64(_canReceiveAfter[i]), uint64(_expiryTime[i])); } return true; } diff --git a/contracts/modules/TransferManager/GTM/GeneralTransferManagerProxy.sol b/contracts/modules/TransferManager/GTM/GeneralTransferManagerProxy.sol index 417c63766..fd44b9fbf 100644 --- a/contracts/modules/TransferManager/GTM/GeneralTransferManagerProxy.sol +++ b/contracts/modules/TransferManager/GTM/GeneralTransferManagerProxy.sol @@ -26,9 +26,9 @@ contract GeneralTransferManagerProxy is GeneralTransferManagerStorage, ModuleSto { require(_implementation != address(0), "Implementation address should not be 0x"); _upgradeTo(_version, _implementation); - transferRequirements[0] = TransferRequirements(true, true, true, true); - transferRequirements[1] = TransferRequirements(false, true, false, false); - transferRequirements[2] = TransferRequirements(true, false, false, false); + transferRequirements[uint8(TransferType.GENERAL)] = TransferRequirements(true, true, true, true); + transferRequirements[uint8(TransferType.ISSUANCE)] = TransferRequirements(false, true, false, false); + transferRequirements[uint8(TransferType.REDEMPTION)] = TransferRequirements(true, false, false, false); } } diff --git a/contracts/modules/TransferManager/GTM/GeneralTransferManagerStorage.sol b/contracts/modules/TransferManager/GTM/GeneralTransferManagerStorage.sol index 1f1d6a07d..4e61eb75f 100644 --- a/contracts/modules/TransferManager/GTM/GeneralTransferManagerStorage.sol +++ b/contracts/modules/TransferManager/GTM/GeneralTransferManagerStorage.sol @@ -10,6 +10,8 @@ contract GeneralTransferManagerStorage { bytes32 public constant INVESTORFLAGS = "INVESTORFLAGS"; uint256 internal constant ONE = uint256(1); + enum TransferType { GENERAL, ISSUANCE, REDEMPTION } + //Address from which issuances come address public issuanceAddress; @@ -32,6 +34,6 @@ contract GeneralTransferManagerStorage { bool toRestricted; } - mapping(uint256 => TransferRequirements) public transferRequirements; + mapping(uint8 => TransferRequirements) public transferRequirements; // General = 0, Issuance = 1, Redemption = 2 } diff --git a/contracts/modules/TransferManager/MATM/ManualApprovalTransferManager.sol b/contracts/modules/TransferManager/MATM/ManualApprovalTransferManager.sol index cc16b5046..1d44d6d6a 100644 --- a/contracts/modules/TransferManager/MATM/ManualApprovalTransferManager.sol +++ b/contracts/modules/TransferManager/MATM/ManualApprovalTransferManager.sol @@ -59,14 +59,14 @@ contract ManualApprovalTransferManager is ManualApprovalTransferManagerStorage, address _from, address _to, uint256 _amount, - bytes calldata _data + bytes calldata /* _data */ ) external onlySecurityToken returns(Result) { - (Result success, bytes32 esc) = verifyTransfer(_from, _to, _amount, _data); + (Result success, bytes32 esc) = _verifyTransfer(_from, _to, _amount); if (esc != bytes32(0)) { uint256 index = approvalIndex[_from][_to] - 1; ManualApproval storage approval = approvals[index]; @@ -91,6 +91,18 @@ contract ManualApprovalTransferManager is ManualApprovalTransferManagerStorage, public view returns(Result, bytes32) + { + return _verifyTransfer(_from, _to, _amount); + } + + function _verifyTransfer( + address _from, + address _to, + uint256 _amount + ) + internal + view + returns(Result, bytes32) { uint256 index = approvalIndex[_from][_to]; if (!paused && index != 0) { @@ -147,13 +159,13 @@ contract ManualApprovalTransferManager is ManualApprovalTransferManagerStorage, * @param _descriptions is the description array for these manual approvals */ function addManualApprovalMulti( - address[] calldata _from, - address[] calldata _to, - uint256[] calldata _allowances, - uint256[] calldata _expiryTimes, - bytes32[] calldata _descriptions + address[] memory _from, + address[] memory _to, + uint256[] memory _allowances, + uint256[] memory _expiryTimes, + bytes32[] memory _descriptions ) - external + public withPerm(ADMIN) { _checkInputLengthArray(_from, _to, _allowances, _expiryTimes, _descriptions); diff --git a/contracts/modules/TransferManager/PTM/PercentageTransferManager.sol b/contracts/modules/TransferManager/PTM/PercentageTransferManager.sol index 34afae73c..5f3971b11 100644 --- a/contracts/modules/TransferManager/PTM/PercentageTransferManager.sol +++ b/contracts/modules/TransferManager/PTM/PercentageTransferManager.sol @@ -41,12 +41,12 @@ contract PercentageTransferManager is PercentageTransferManagerStorage, Transfer address _from, address _to, uint256 _amount, - bytes calldata _data + bytes calldata /* _data */ ) external returns(Result) { - (Result success,) = verifyTransfer(_from, _to, _amount, _data); + (Result success,) = _verifyTransfer(_from, _to, _amount); return success; } @@ -65,6 +65,18 @@ contract PercentageTransferManager is PercentageTransferManagerStorage, Transfer public view returns(Result, bytes32) + { + return _verifyTransfer(_from, _to, _amount); + } + + function _verifyTransfer( + address _from, + address _to, + uint256 _amount + ) + internal + view + returns(Result, bytes32) { if (!paused) { if (_from == address(0) && allowPrimaryIssuance) { diff --git a/contracts/modules/TransferManager/VRTM/VolumeRestrictionTM.sol b/contracts/modules/TransferManager/VRTM/VolumeRestrictionTM.sol index 43d3aa164..12bef17d8 100644 --- a/contracts/modules/TransferManager/VRTM/VolumeRestrictionTM.sol +++ b/contracts/modules/TransferManager/VRTM/VolumeRestrictionTM.sol @@ -450,6 +450,10 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, TransferManager { * @param _holder Address of the user */ function removeIndividualRestriction(address _holder) public withPerm(ADMIN) { + _removeIndividualRestriction(_holder); + } + + function _removeIndividualRestriction(address _holder) internal { require(_holder != address(0)); require(individualRestrictions.individualRestriction[_holder].endTime != 0); individualRestrictions.individualRestriction[_holder] = VolumeRestriction(0, 0, 0, 0, RestrictionType(0)); @@ -464,9 +468,9 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, TransferManager { * @notice use to remove the individual restriction for a given address * @param _holders Array of address of the user */ - function removeIndividualRestrictionMulti(address[] calldata _holders) external { + function removeIndividualRestrictionMulti(address[] memory _holders) public withPerm(ADMIN) { for (uint256 i = 0; i < _holders.length; i++) { - removeIndividualRestriction(_holders[i]); + _removeIndividualRestriction(_holders[i]); } } @@ -475,6 +479,10 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, TransferManager { * @param _holder Address of the user */ function removeIndividualDailyRestriction(address _holder) public withPerm(ADMIN) { + _removeIndividualDailyRestriction(_holder); + } + + function _removeIndividualDailyRestriction(address _holder) internal { require(_holder != address(0)); require(individualRestrictions.individualDailyRestriction[_holder].endTime != 0); individualRestrictions.individualDailyRestriction[_holder] = VolumeRestriction(0, 0, 0, 0, RestrictionType(0)); @@ -487,9 +495,9 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, TransferManager { * @notice use to remove the individual daily restriction for a given address * @param _holders Array of address of the user */ - function removeIndividualDailyRestrictionMulti(address[] calldata _holders) external { + function removeIndividualDailyRestrictionMulti(address[] memory _holders) public withPerm(ADMIN) { for (uint256 i = 0; i < _holders.length; i++) { - removeIndividualDailyRestriction(_holders[i]); + _removeIndividualDailyRestriction(_holders[i]); } } @@ -664,7 +672,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, TransferManager { * @param _rollingPeriodInDays Rolling period in days (Minimum value should be 1 day) * @param _endTime Unix timestamp at which restriction effects will gets end. * @param _restrictionType Whether it will be `Fixed` (fixed no. of tokens allowed to transact) - * or `Percentage` (tokens are calculated as per the totalSupply in the fly). + * or `Percentage` (tokens are calculated as per the totalSupply in the fly). */ function modifyDefaultRestriction( uint256 _allowedTokens, @@ -703,7 +711,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, TransferManager { * @param _startTime Unix timestamp at which restriction get into effect * @param _endTime Unix timestamp at which restriction effects will gets end. * @param _restrictionType Whether it will be `Fixed` (fixed no. of tokens allowed to transact) - * or `Percentage` (tokens are calculated as per the totalSupply in the fly). + * or `Percentage` (tokens are calculated as per the totalSupply in the fly). */ function modifyDefaultDailyRestriction( uint256 _allowedTokens, @@ -748,7 +756,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, TransferManager { VolumeRestriction memory _restriction ) internal - view + view returns ( Result success, uint256 fromTimestamp, @@ -781,7 +789,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, TransferManager { _isDefault, fromTimestamp, BokkyPooBahsDateTimeLibrary.diffDays(fromTimestamp, now), - + daysCovered, _bucketDetails ); @@ -793,7 +801,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, TransferManager { allowedDefault = false; } } - + // reusing the local variable to avoid stack too deep error // here variable endTime is representing the allowedDailyAmount (allowedDaily, dailyTime, endTime) = _dailyTxCheck(_amount, _from, _isDefault, _bucketDetails.dailyLastTradedDayTime, dailyRestriction); @@ -811,13 +819,13 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, TransferManager { ) internal view - returns (uint256) - { + returns (uint256) + { if (now > dailyRestriction.endTime || now < dailyRestriction.startTime) return allowedAmount; else if (now > restriction.endTime || now < restriction.startTime) return allowedDailyAmount; - else + else return Math.min(allowedDailyAmount, allowedAmount); } @@ -826,7 +834,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, TransferManager { * default to individual or vice versa. It will return true when last transaction traded by the user * and the current txn timestamp lies in the same day. * NB - Instead of comparing the current day transaction amount, we are comparing the total amount traded - * on the lastTradedDayTime that makes the restriction strict. The reason is not availability of amount + * on the lastTradedDayTime that makes the restriction strict. The reason is not availability of amount * that transacted on the current day (because of bucket desgin). */ function _isValidAmountAfterRestrictionChanges( @@ -877,7 +885,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, TransferManager { txSumOfDay = bucketData.defaultBucket[_from][_dailyLastTradedDayTime]; else txSumOfDay = bucketData.bucket[_from][_dailyLastTradedDayTime]; - (bool isAllowed, uint256 allowedAmount) = _checkValidAmountToTransact(_amount, _from, _isDefault, _restriction, txSumOfDay); + (bool isAllowed, uint256 allowedAmount) = _checkValidAmountToTransact(_amount, _from, _isDefault, _restriction, txSumOfDay); return (isAllowed, _dailyLastTradedDayTime, allowedAmount); } return (true, _dailyLastTradedDayTime, _amount); @@ -1088,7 +1096,7 @@ contract VolumeRestrictionTM is VolumeRestrictionTMStorage, TransferManager { uint256 currentBalance = (msg.sender == securityToken) ? (IERC20(securityToken).balanceOf(_tokenHolder)).add(_additionalBalance) : IERC20(securityToken).balanceOf(_tokenHolder); if (paused) return (_partition == UNLOCKED ? currentBalance: 0); - + (,fromTimestamp,,,dailyTime,,allowedAmountToTransact,) = _verifyTransfer(_tokenHolder, 0); if (_partition == LOCKED) { if (allowedAmountToTransact == 0 && fromTimestamp == 0 && dailyTime == 0) diff --git a/contracts/storage/EternalStorage.sol b/contracts/storage/EternalStorage.sol index 40175f31d..a3b914b60 100644 --- a/contracts/storage/EternalStorage.sol +++ b/contracts/storage/EternalStorage.sol @@ -56,6 +56,10 @@ contract EternalStorage { stringStorage[_key] = _value; } + function set(bytes32 _key, bytes memory _value) internal { + bytesStorage[_key] = _value; + } + //////////////////////////// // deleteArray functions //////////////////////////// diff --git a/contracts/tokens/SecurityToken.sol b/contracts/tokens/SecurityToken.sol index b432f33de..65ab132d9 100644 --- a/contracts/tokens/SecurityToken.sol +++ b/contracts/tokens/SecurityToken.sol @@ -53,14 +53,6 @@ contract SecurityToken is ERC20, ReentrancyGuard, SecurityTokenStorage, IERC1594 event FreezeIssuance(); // Emit when transfers are frozen or unfrozen event FreezeTransfers(bool _status); - // Emit when Module get archived from the securityToken - event ModuleArchived(uint8[] _types, address _module); - // Emit when Module get unarchived from the securityToken - event ModuleUnarchived(uint8[] _types, address _module); - // Emit when Module get removed from the securityToken - event ModuleRemoved(uint8[] _types, address _module); - // Emit when the budget allocated to a module is changed - event ModuleBudgetChanged(uint8[] _moduleTypes, address _module, uint256 _oldBudget, uint256 _budget); // Emit when new checkpoint created event CheckpointCreated(uint256 indexed _checkpointId, uint256 _investorLength); // Events to log controller actions @@ -71,6 +63,15 @@ contract SecurityToken is ERC20, ReentrancyGuard, SecurityTokenStorage, IERC1594 event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); event TokenUpgraded(uint8 _major, uint8 _minor, uint8 _patch); + // Emit when Module get archived from the securityToken + event ModuleArchived(uint8[] _types, address _module); //Event emitted by the tokenLib. + // Emit when Module get unarchived from the securityToken + event ModuleUnarchived(uint8[] _types, address _module); //Event emitted by the tokenLib. + // Emit when Module get removed from the securityToken + event ModuleRemoved(uint8[] _types, address _module); //Event emitted by the tokenLib. + // Emit when the budget allocated to a module is changed + event ModuleBudgetChanged(uint8[] _moduleTypes, address _module, uint256 _oldBudget, uint256 _budget); //Event emitted by the tokenLib. + /** * @notice Initialization function * @dev Expected to be called atomically with the proxy being created, by the owner of the token @@ -213,7 +214,15 @@ contract SecurityToken is ERC20, ReentrancyGuard, SecurityTokenStorage, IERC1594 _addModuleData(moduleTypes, _moduleFactory, module, moduleCost, _budget, _label, _archived); } - function _addModuleData(uint8[] memory _moduleTypes, address _moduleFactory, address _module, uint256 _moduleCost, uint256 _budget, bytes32 _label, bool _archived) internal { + function _addModuleData( + uint8[] memory _moduleTypes, + address _moduleFactory, + address _module, + uint256 _moduleCost, + uint256 _budget, + bytes32 _label, + bool _archived + ) internal { bytes32 moduleName = IModuleFactory(_moduleFactory).name(); uint256[] memory moduleIndexes = new uint256[](_moduleTypes.length); uint256 i; @@ -265,6 +274,10 @@ contract SecurityToken is ERC20, ReentrancyGuard, SecurityTokenStorage, IERC1594 */ function upgradeToken() external { _onlyOwner(); + // 10 is the number of module types to check for incompatibilities before upgrading. + // The number is hard coded and kept low to keep usage low. + // We currently have 7 module types. If we ever create more than 3 new module types, + // We will upgrade the implementation accordinly. We understand the limitations of this approach. IUpgradableTokenFactory(tokenFactory).upgradeToken(10); emit TokenUpgraded(securityTokenVersion.major, securityTokenVersion.minor, securityTokenVersion.patch); } @@ -430,7 +443,7 @@ contract SecurityToken is ERC20, ReentrancyGuard, SecurityTokenStorage, IERC1594 function _transferWithData(address _from, address _to, uint256 _value, bytes memory _data) internal { _isValidTransfer(_updateTransfer(_from, _to, _value, _data)); - // Using the internal function instead of super.transfer() in the favour of reducing the code size + // Using the internal function instead of super.transfer() in the favour of reducing the code size _transfer(_from, _to, _value); } @@ -505,12 +518,12 @@ contract SecurityToken is ERC20, ReentrancyGuard, SecurityTokenStorage, IERC1594 bytes memory _data, address _operator, bytes memory _operatorData - ) + ) internal - returns(bytes32 toPartition) + returns(bytes32 toPartition) { _isValidPartition(_partition); - // Avoiding to add this check + // Avoiding to add this check // require(balanceOfByPartition(_partition, msg.sender) >= _value); // NB - Above condition will be automatically checked using the executeTransfer() function execution. // NB - passing `_additionalBalance` value is 0 because accessing the balance before transfer @@ -527,21 +540,21 @@ contract SecurityToken is ERC20, ReentrancyGuard, SecurityTokenStorage, IERC1594 // balance otherwise return UNLOCKED if (_afterBalance.sub(_beforeBalance) == _value) toPartition = LOCKED; - // Returning the same partition UNLOCKED + // Returning the same partition UNLOCKED toPartition = UNLOCKED; } /////////////////////// /// Operator Management /////////////////////// - + /** * @notice Authorises an operator for all partitions of `msg.sender`. * NB - Allowing investors to authorize an investor to be an operator of all partitions * but it doesn't mean we operator is allowed to transfer the LOCKED partition values. * Logic for this restriction is written in `operatorTransferByPartition()` function. * @param _operator An address which is being authorised. - */ + */ function authorizeOperator(address _operator) public { _approve(msg.sender, _operator, uint(-1)); emit AuthorizedOperator(_operator, msg.sender); @@ -598,9 +611,9 @@ contract SecurityToken is ERC20, ReentrancyGuard, SecurityTokenStorage, IERC1594 uint256 _value, bytes calldata _data, bytes calldata _operatorData - ) + ) external - returns (bytes32) + returns (bytes32) { // For the current release we are only allowing UNLOCKED partition tokens to transact _validateOperatorAndPartition(_partition, _from, msg.sender); @@ -628,7 +641,7 @@ contract SecurityToken is ERC20, ReentrancyGuard, SecurityTokenStorage, IERC1594 // - checkpoints are updated after the transfer managers are called. This allows TMs to create //checkpoints as though they have been created before the current transactions, // - to avoid the situation where a transfer manager transfers tokens, and this function is called recursively, - //the function is marked as nonReentrant. This means that no TM can transfer (or mint / burn) tokens. + //the function is marked as nonReentrant. This means that no TM can transfer (or mint / burn) tokens in the execute transfer function. _adjustInvestorCount(_from, _to, _value); verified = _executeTransfer(_from, _to, _value, _data); _adjustBalanceCheckpoints(_from); @@ -709,7 +722,7 @@ contract SecurityToken is ERC20, ReentrancyGuard, SecurityTokenStorage, IERC1594 uint256 _value, bytes memory _data ) - public // changed to public to save the code size and reuse the function + public // changed to public to save the code size and reuse the function { _isIssuanceAllowed(); _onlyModuleOrOwner(MINT_KEY); @@ -736,10 +749,10 @@ contract SecurityToken is ERC20, ReentrancyGuard, SecurityTokenStorage, IERC1594 * @param _values A list of number of tokens get minted and transfer to corresponding address of the investor from _tokenHolders[] list * @return success */ - function issueMulti(address[] calldata _tokenHolders, uint256[] calldata _values) external { + function issueMulti(address[] memory _tokenHolders, uint256[] memory _values) public { _isIssuanceAllowed(); _onlyModuleOrOwner(MINT_KEY); - // Remove reason string to reduce the code size + // Remove reason string to reduce the code size require(_tokenHolders.length == _values.length); for (uint256 i = 0; i < _tokenHolders.length; i++) { _issue(_tokenHolders[i], _values[i], ""); @@ -796,8 +809,8 @@ contract SecurityToken is ERC20, ReentrancyGuard, SecurityTokenStorage, IERC1594 address _operator, bytes memory _data, bytes memory _operatorData - ) - internal + ) + internal { _redeem(_from, _value, _data); emit RedeemedByPartition(_partition, _operator, _from, _value, _data, _operatorData); @@ -818,10 +831,10 @@ contract SecurityToken is ERC20, ReentrancyGuard, SecurityTokenStorage, IERC1594 uint256 _value, bytes calldata _data, bytes calldata _operatorData - ) + ) external { - _onlyModule(BURN_KEY); + _onlyModule(BURN_KEY); require(_operatorData[0] != 0); _zeroAddressCheck(_tokenHolder); _validateOperatorAndPartition(_partition, _tokenHolder, msg.sender); @@ -932,7 +945,7 @@ contract SecurityToken is ERC20, ReentrancyGuard, SecurityTokenStorage, IERC1594 return (false, 0x50, bytes32(0)); } (success, appCode) = TokenLib.verifyTransfer(modules[TRANSFER_KEY], modulesToData, _from, _to, _value, _data, transfersFrozen); - return TokenLib.canTransfer(success, appCode, _to, _value, balanceOf(_from), balanceOf(_to)); + return TokenLib.canTransfer(success, appCode, _to, _value, balanceOf(_from)); } /** @@ -957,7 +970,7 @@ contract SecurityToken is ERC20, ReentrancyGuard, SecurityTokenStorage, IERC1594 external view returns (byte esc, bytes32 appStatusCode, bytes32 toPartition) - { + { if (_partition == UNLOCKED) { bool success; (success, esc, appStatusCode) = _canTransfer(_from, _to, _value, _data); @@ -968,7 +981,7 @@ contract SecurityToken is ERC20, ReentrancyGuard, SecurityTokenStorage, IERC1594 } return (esc, appStatusCode, toPartition); } - return (0x50, bytes32(0), bytes32(0)); + return (0x50, bytes32(0), bytes32(0)); } /**