Skip to content

Commit dba24b0

Browse files
committed
resolve conflicts
2 parents 2d0b387 + 28fdd92 commit dba24b0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+1073
-744
lines changed

CHANGELOG.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ All notable changes to this project will be documented in this file.
1111
* Fixed `addModule` function to be backwards compatible and call the new `addModuleWithLabel` function with an empty label.
1212
* Fixed event `ModuleAdded` to also emit `_label`.
1313
* Fixed function `getModule` to also return the respective module label.
14+
* Added datastore that is used to store data like investor list that is shared among modules.
15+
* `getInvestorCount()` now returns length of investor array that is everyone who ever held some st or has kyc data attached.
16+
* `holderCount()` returns the number of current st holders.
17+
* Added flags for Investors. Accredited and canbuyfromsto are now flags
1418

1519
## STR
1620
* Introduce new contract `STRGetter.sol`. It only contains the getter functions of the STR.
@@ -19,7 +23,9 @@ All notable changes to this project will be documented in this file.
1923
* Removed `_polyToken` parameter from `initialize` function in `SecurityTokenRegistry`.
2024

2125
## GeneralTransferManager
22-
* Add `_isAccredited` variable in the `modifyWhitelist()` function of the GeneralTransferManager.
26+
* `modifyWhitelist()` function renamed to `modifyKYCData()`.
27+
* Added functions to modify and get flags
28+
* `canBuyFromSto` is now `canNotBuyFromSto` and it is the flag `1`
2329

2430
## Generalize
2531
* Removed `_polyAddress` parameter from constructors of all modules and module factories.

contracts/datastore/DataStore.sol

Lines changed: 129 additions & 89 deletions
Large diffs are not rendered by default.

contracts/datastore/DataStoreStorage.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,6 @@ contract DataStoreStorage {
1616
mapping (bytes32 => address[]) internal addressArrayData;
1717
mapping (bytes32 => bool[]) internal boolArrayData;
1818

19-
uint8 constant DATA_KEY = 6;
20-
bytes32 public constant MANAGEDATA = "MANAGEDATA";
19+
uint8 internal constant DATA_KEY = 6;
20+
bytes32 internal constant MANAGEDATA = "MANAGEDATA";
2121
}

contracts/interfaces/IDataStore.sol

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,4 +125,12 @@ interface IDataStore {
125125
function getAddressArrayElement(bytes32 _key, uint256 _index) external view returns(address);
126126

127127
function getBoolArrayElement(bytes32 _key, uint256 _index) external view returns(bool);
128+
129+
function getUint256ArrayElements(bytes32 _key, uint256 _startIndex, uint256 _endIndex) external view returns(uint256[] memory);
130+
131+
function getBytes32ArrayElements(bytes32 _key, uint256 _startIndex, uint256 _endIndex) external view returns(bytes32[] memory);
132+
133+
function getAddressArrayElements(bytes32 _key, uint256 _startIndex, uint256 _endIndex) external view returns(address[] memory);
134+
135+
function getBoolArrayElements(bytes32 _key, uint256 _startIndex, uint256 _endIndex) external view returns(bool[] memory);
128136
}

contracts/interfaces/ISecurityToken.sol

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,11 @@ interface ISecurityToken {
382382
*/
383383
function getInvestorCount() external view returns(uint256);
384384

385+
/**
386+
* @notice Gets the holder count (investors with non zero balance)
387+
*/
388+
function holderCount() external view returns(uint256);
389+
385390
/**
386391
* @notice Overloaded version of the transfer function
387392
* @param _to receiver of transfer

contracts/libraries/TokenLib.sol

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
pragma solidity ^0.5.0;
22

33
import "../interfaces/IPoly.sol";
4+
import "../interfaces/IDataStore.sol";
45
import "../tokens/SecurityTokenStorage.sol";
56
import "../interfaces/ITransferManager.sol";
67
import "openzeppelin-solidity/contracts/math/SafeMath.sol";
@@ -10,6 +11,9 @@ library TokenLib {
1011

1112
using SafeMath for uint256;
1213

14+
bytes32 internal constant WHITELIST = "WHITELIST";
15+
bytes32 internal constant INVESTORSKEY = 0xdf3a8dd24acdd05addfc6aeffef7574d2de3f844535ec91e8e0f3e45dba96731; //keccak256(abi.encodePacked("INVESTORS"))
16+
1317
// Emit when Module is archived from the SecurityToken
1418
event ModuleArchived(uint8[] _types, address _module);
1519
// Emit when Module is unarchived from the SecurityToken
@@ -194,40 +198,45 @@ library TokenLib {
194198

195199
/**
196200
* @notice Keeps track of the number of non-zero token holders
197-
* @param _investorData Date releated to investor metrics
201+
* @param _holderCount Number of current token holders
198202
* @param _from Sender of transfer
199203
* @param _to Receiver of transfer
200204
* @param _value Value of transfer
201205
* @param _balanceTo Balance of the _to address
202206
* @param _balanceFrom Balance of the _from address
207+
* @param _dataStore address of data store
203208
*/
204209
function adjustInvestorCount(
205-
SecurityTokenStorage.InvestorDataStorage storage _investorData,
210+
uint256 _holderCount,
206211
address _from,
207212
address _to,
208213
uint256 _value,
209214
uint256 _balanceTo,
210-
uint256 _balanceFrom
215+
uint256 _balanceFrom,
216+
address _dataStore
211217
)
212218
public
219+
returns(uint256)
213220
{
214221
if ((_value == 0) || (_from == _to)) {
215-
return;
222+
return _holderCount;
216223
}
217224
// Check whether receiver is a new token holder
218225
if ((_balanceTo == 0) && (_to != address(0))) {
219-
_investorData.investorCount = (_investorData.investorCount).add(1);
226+
_holderCount = _holderCount.add(1);
227+
IDataStore dataStore = IDataStore(_dataStore);
228+
if (!_isExistingInvestor(_to, dataStore)) {
229+
dataStore.insertAddress(INVESTORSKEY, _to);
230+
//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
231+
dataStore.setUint256(_getKey(WHITELIST, _to), uint256(1));
232+
}
220233
}
221234
// Check whether sender is moving all of their tokens
222235
if (_value == _balanceFrom) {
223-
_investorData.investorCount = (_investorData.investorCount).sub(1);
224-
}
225-
//Also adjust investor list
226-
if (!_investorData.investorListed[_to] && (_to != address(0))) {
227-
_investorData.investors.push(_to);
228-
_investorData.investorListed[_to] = true;
236+
_holderCount = _holderCount.sub(1);
229237
}
230238

239+
return _holderCount;
231240
}
232241

233242
/**
@@ -284,4 +293,13 @@ library TokenLib {
284293
return (false, bytes32(hex"54"));
285294
}
286295

296+
function _getKey(bytes32 _key1, address _key2) internal pure returns(bytes32) {
297+
return bytes32(keccak256(abi.encodePacked(_key1, _key2)));
298+
}
299+
300+
function _isExistingInvestor(address _investor, IDataStore dataStore) internal view returns(bool) {
301+
uint256 data = dataStore.getUint256(_getKey(WHITELIST, _investor));
302+
//extracts `added` from packed `whitelistData`
303+
return uint8(data) == 0 ? false : true;
304+
}
287305
}

contracts/libraries/VersionUtils.sol

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -110,21 +110,22 @@ library VersionUtils {
110110
/**
111111
* @notice Used to packed the KYC data
112112
*/
113-
function packKYC(uint64 _a, uint64 _b, uint64 _c, uint8 _d, uint8 _e, uint8 _f) internal pure returns(uint256) {
114-
return (uint256(_a) << 152) | (uint256(_b) << 88) | (uint256(_c) << 24) | (uint256(_d) << 16) | (uint256(_e) << 8) | uint256(_f);
113+
function packKYC(uint64 _a, uint64 _b, uint64 _c, uint8 _d) internal pure returns(uint256) {
114+
// this function packs 3 uint64 and a uint8 together in a uint256 to save storage cost
115+
// a is rotated left by 136 bits, b is rotated left by 72 bits and c is rotated left by 8 bits.
116+
// rotation pads empty bits with zeroes so now we can safely do a bitwise OR operation to pack
117+
// all the variables together.
118+
return (uint256(_a) << 136) | (uint256(_b) << 72) | (uint256(_c) << 8) | uint256(_d);
115119
}
116120

117121
/**
118122
* @notice Used to convert packed data into KYC data
119123
* @param _packedVersion Packed data
120124
*/
121-
function unpackKYC(uint256 _packedVersion) internal pure returns(uint64 fromTime, uint64 toTime, uint64 expiryTime, uint8 canBuy, uint8 added, uint8 accredited) {
122-
fromTime = uint64(_packedVersion >> 152);
123-
toTime = uint64(_packedVersion >> 88);
124-
expiryTime = uint64(_packedVersion >> 24);
125-
canBuy = uint8(_packedVersion >> 16);
126-
added = uint8(_packedVersion >> 8);
127-
accredited = uint8(_packedVersion);
125+
function unpackKYC(uint256 _packedVersion) internal pure returns(uint64 fromTime, uint64 toTime, uint64 expiryTime, uint8 added) {
126+
fromTime = uint64(_packedVersion >> 136);
127+
toTime = uint64(_packedVersion >> 72);
128+
expiryTime = uint64(_packedVersion >> 8);
129+
added = uint8(_packedVersion);
128130
}
129-
130131
}

contracts/modules/STO/CappedSTO.sol

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -208,10 +208,10 @@ contract CappedSTO is CappedSTOStorage, STO, ReentrancyGuard {
208208
Observe state and use revert statements to undo rollback when valid conditions are not met.
209209
*/
210210
function _postValidatePurchase(
211-
address, /*_beneficiary*/
211+
address _beneficiary,
212212
uint256 /*_investedAmount*/
213-
) internal pure {
214-
// optional override
213+
) internal view {
214+
require(_canBuy(_beneficiary), "Unauthorized");
215215
}
216216

217217
/**

contracts/modules/STO/DummySTO.sol

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ contract DummySTO is DummySTOStorage, STO {
4848
function generateTokens(address _investor, uint256 _amount) public withPerm(ADMIN) {
4949
require(!paused, "Should not be paused");
5050
require(_amount > 0, "Amount should be greater than 0");
51+
require(_canBuy(_investor), "Unauthorized");
5152
ISecurityToken(securityToken).issue(_investor, _amount, "");
5253
if (investors[_investor] == 0) {
5354
investorCount = investorCount + 1;

contracts/modules/STO/PreSaleSTO.sol

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,14 @@ contract PreSaleSTO is PreSaleSTOStorage, STO {
7171
uint256 _amount,
7272
uint256 _etherContributed,
7373
uint256 _polyContributed
74-
)
75-
public
76-
withPerm(PRE_SALE_ADMIN)
74+
)
75+
public
76+
withPerm(PRE_SALE_ADMIN)
7777
{
7878
/*solium-disable-next-line security/no-block-members*/
7979
require(now <= endTime, "Already passed Endtime");
8080
require(_amount > 0, "No. of tokens provided should be greater the zero");
81+
require(_canBuy(_investor), "Unauthorized");
8182
ISecurityToken(securityToken).issue(_investor, _amount, "");
8283
if (investors[_investor] == uint256(0)) {
8384
investorCount = investorCount.add(1);
@@ -101,9 +102,9 @@ contract PreSaleSTO is PreSaleSTOStorage, STO {
101102
uint256[] memory _amounts,
102103
uint256[] memory _etherContributed,
103104
uint256[] memory _polyContributed
104-
)
105-
public
106-
withPerm(PRE_SALE_ADMIN)
105+
)
106+
public
107+
withPerm(PRE_SALE_ADMIN)
107108
{
108109
require(_investors.length == _amounts.length, "Mis-match in length of the arrays");
109110
require(_etherContributed.length == _polyContributed.length, "Mis-match in length of the arrays");

0 commit comments

Comments
 (0)