Skip to content

Commit

Permalink
Merge 2.1 / 2.2 functionality (#564)
Browse files Browse the repository at this point in the history
* Merge 2.1 / 2.2 functionality

* Fix some tests

* reduce size
  • Loading branch information
adamdossa authored Feb 21, 2019
1 parent 3375bca commit 3613255
Show file tree
Hide file tree
Showing 10 changed files with 839 additions and 169 deletions.
62 changes: 53 additions & 9 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,14 @@ All notable changes to this project will be documented in this file.

[__2.1.0__](https://www.npmjs.com/package/polymath-core?activeTab=readme) __13-09-18__

## CappedSTO 2.0.1

## CappedSTO 2.1.0
* `rate` is now accepted as multiplied by 10^18 to allow settting higher price than 1ETH/POLY per token.
* Indivisble tokens are now supported. When trying to buy partial tokens, allowed full units of tokens will be purchased and remaining funds will be returned.

## USDTieredSTO 2.1.0
* Added `stableCoinsRaised` function that returns amount of individual stable coin raised when address of that stable coin is passed.
* Added support for multiple stable coins in USDTSTO.
* Added `buyTokensView` and `getTokensMintedByTier` to USDTSTO.
* Added `getSTODetails` to USDTSTO.
* Added an Array of Tiers that will hold data about every tier in USDTSTO.
Expand All @@ -48,27 +51,68 @@ All notable changes to this project will be documented in this file.
* Removed individual mappings for tier data removed in UDSTSTO.
* Removed the old Proxy deployment method of USDTieredSTO and adopt the new inherited proxy deployment approach.
* Bump the version to `2.1.0`
* Added `getAccreditedData` to return accredited & non-accredited investor data.
* Event `TokenPurchase` has uint256 tier instead of uint8 tier.
* Event `SetAddresses` has non-indexed array of address of `_usdTokens` rather than single indexed address.
* Added `getUsdTokens()` function that returns array of accepted stable coin (usd token) addresses.
* Pass an array of `_usdToken` address in `configure` function instead of singleton address. This will require changes in bytes data generation when deploying a usdtsto through factory.

## GeneralTransferManager
* `getInvestors`, `getAllInvestorsData`, `getInvestorsData` added to GTM to allow easy data queries.
* `modifyDefaults(uint64 _defaultFromTime, uint64 _defaultToTime)` added which sets a default timestamp used when `fromTime` or `toTime` are 0
* `changeDefaults(uint64 _defaultFromTime, uint64 _defaultToTime)` added which sets a default timestamp used when `fromTime` or `toTime` are 0.
* Add `address[] public investors` to record a list of all addresses that have been added to the whitelist (`getInvestors`).
* General Transfer Manager: Fix for when `allowAllWhitelistIssuances` is FALSE
* General Transfer Manager: Make GTM a Proxy based implementation to reduce deployment gas costs
* Fix for when `allowAllWhitelistIssuances` is FALSE
* Make GTM a Proxy based implementation to reduce deployment gas costs
* Changed the version of `GeneralTransferManagerFactory` from `1.0.0` to `2.1.0`.
* `_investor` and `_addedBy` is now indexed in the `ModifyWhitelist` event.
* Add public variable `defaults` to get the offset timing.

## Manual Approval TransferManager
* Removed `0x0` check for the `_from` address to `ManualApprovalTransferManager`. This allows for the Issuer/Transfer Agent to approve a one-off mint of tokens that otherwise would not be possible.
* Changed the version of `ManualApprovalTransferManagerFactory` from `1.0.0` to `2.1.0`.
* Deployed 2.0.1 `ManualApprovalTransferManagerFactory` to address 0x6af2afad53cb334e62b90ddbdcf3a086f654c298
* Add `getActiveApprovalsToUser()` function to access all the active approvals for a user whether user is in the `from` or in `to`.
* Add `getApprovalDetails()` to get the details of the approval corresponds to `_from` and `_to` address.
* Add feature to modify the details of the active approval using `modifyApproval()` & `modifyApprovalMulti()`.
* Add `addManualApprovalMulti()` and `revokeManualApprovalMulti()` batch function for adding and revoking the manual approval respectively.
* Add `_description` parameter during the `addManualApproval()` function call. It will be a `bytes32` variable which depicts the cause of manual approval.
* Remove `addManualBlocking()` , `revokeManualBlocking()` functions.
* Add `getTotalApprovalsLength()` to get the number of active approvals.
* Add `getAllApprovals()` to get the details of all approvals.

## Dividends
* Changed the version of `ERC20DividendCheckpointFactory` & `EtherDividendCheckpointFactory` from `1.0.0` to `2.1.0`.
* Applied proxy pattern to Dividends modules
* Applied proxy pattern to Dividends modules.
* During the launch of dividend module issuer need to pass the reclaimed wallet that receive the left over funds from the module.
i.e pass `_wallet` in `configure()` function of dividend module. It emits `SetWallet` event for the confirmation of the same.
* Add `changeWallet()` function to change the reclaimed wallet address (only be called by the owner).
* Add `getDividendsData()` getter to receive the details about all the dividend.
* Add `getDividendData()` getter to receive the details about the particular dividend by passing a corresponding dividend index.
* Add `getDividendProgress()` getter to retrieves the list of investors and their details corresponds to particular dividend.
* Add `getCheckpointData()` use to retrieves list of investors, their balances, and their current withholding tax percentage corresponds to checkpointId.
* `isExcluded()` a view function added to check whether an address is excluded from claming a dividend or not.
* `isClaimed()` a view function added to checks whether an address has claimed a dividend or not.
* DividendIndex is indexed in the events `ERC20DividendClaimed`, `ERC20DividendReclaimed`, `ERC20DividendWithholdingWithdrawn`. Similarly for the Ether dividend module `EtherDividendClaimed`, `EtherDividendReclaimed`, `EtherDividendClaimFailed`, `EtherDividendWithholdingWithdrawn`.
* `EXCLUDED_ADDRESS_LIMIT` changed from 50 to 150.

## Experimental modules
* Remove the `SingleTradeVolumeRestrictionTMFactory.sol` and its corresponding module `SingleTradeVolumeRestrictionTM.sol`.
* Add the new TM called `BlacklistTransferManager.sol` and its corresponding factory `BlacklistTransferManagerFactory.sol`.
* Chnage the name of module from `LockupVolumeRestrictionTM.sol` to `LockUpTransferManager.sol`, similarly factory become `LockUpTransferManagerFactory.sol`.
* Add new module called `VestingEscrowWallet.sol` and its corresponding factory `VestingEscrowWalletFactory.sol`.

## STR & MR
* `getArrayAddress(), getArrayBytes32(), getArrayUint()` are now public getters.
* `getUintValues(), getBoolValues(), getStringValues(), getAddressValues(), getBytes32Values(), getBytesValues()` rename to `getUintValue(), getBoolValue(), getStringValue(), getAddressValue(), getBytes32Value(), getBytesValue()`. #488

## Added
* Add new module called `VolumeRestrictionTM.sol` under the TransferManager modules list. It will be used to restrict the token
volume traded in a given rolling period.

## Changed
* `getAllModulesAndPermsFromTypes()` does not take securityToken address as a parameter anymore.


# v1.5.0 - Release Candidate

[__1.5.0__](https://www.npmjs.com/package/polymath-core?activeTab=readme) __15-08-18__
Expand Down Expand Up @@ -107,7 +151,7 @@ All notable changes to this project will be documented in this file.
* 0x0 and duplicate address in exclusions are no longer allowed in dividend modules.
* All permissions are denied if no permission manager is active.
* 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
Expand Down Expand Up @@ -339,7 +383,7 @@ allowed)
* __buyTokensWithPoly__ has only one argument called `_investedPoly` only. Beneficiary Address should be its msg.sender.
* __getRaiseEther()__ function name changed to __getRaisedEther()__.
* __getRaisePoly()__ function name changed to __getRaisedPoly()__.
* `LogModuleAdded` emit one more variable called ___budget__.
* `LogModuleAdded` emit one more variable called __budget__.
* `modules` mapping in the securityToken contract now returns __the array of ModuleData__.

## Removed
Expand All @@ -351,7 +395,7 @@ allowed)

## Added
* ModuleRegistry contract will provide the list of modules by there types.
* `SecurityTokenRegistry` is now working on the basis of the proxy version of the securitytoken contract. For that SecurityTokenRegistry has one more variable in the constructor called _STVersionProxy .
* `SecurityTokenRegistry` is now working on the basis of the proxy version of the securitytoken contract. For that SecurityTokenRegistry has one more variable in the constructor called _STVersionProxy_ .
* `setProtocolVersion` new function added in the SecurityTokenRegistry to set the protocol version followed to generate the securityToken. Only be called by the `polymath admin`.
* `SecurityToken` now have the integration with polyToken. At the time of `addModule()` SecurityToken approve the cost of the module to moduleFactory as the spender.
* New function `withdrawPoly(uint256 _amount)` is added to withdrawal the unused POLY from the securityToken contract. Called only by the owner of the contract.
Expand All @@ -378,7 +422,7 @@ allowed)
* Deployment of the securityToken is now performed by the proxy contracts and call being generated form the SecurityTokenRegistry.
* `TickerRegistrar` renamed as `TickerRegistry`.
* TickerRegistry is now Ownable contract.
* `setTokenRegistrar` functio of TickerRegistry renamed to `setTokenRegistry`.
* `setTokenRegistrar` function of TickerRegistry renamed to `setTokenRegistry`.
* SecurityToken constructor has one change in the variable. i.e `_moduleRegistry` contract address is replaced by the `_owner` address.
* Their is no `_perm` parameter in the `addModule()` function of the securityToken contract. Now only 4 parameters left.
* Type of Mudules changed
Expand Down
109 changes: 82 additions & 27 deletions contracts/STRGetter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import "./libraries/Util.sol";
import "./libraries/Encoder.sol";
import "./interfaces/IOwnable.sol";
import "./libraries/VersionUtils.sol";
import "./interfaces/ISecurityToken.sol";
import "./modules/PermissionManager/IPermissionManager.sol";

contract STRGetter is EternalStorage {

Expand All @@ -17,28 +19,33 @@ contract STRGetter is EternalStorage {
* @param _owner is the address which owns the list of tickers
*/
function getTickersByOwner(address _owner) external view returns(bytes32[] memory) {
uint counter = 0;
uint256 count = 0;
// accessing the data structure userTotickers[_owner].length
bytes32[] memory tickers = getArrayBytes32(Encoder.getKey("userToTickers", _owner));
uint i;
for (i = 0; i < tickers.length; i++) {
string memory ticker = Util.bytes32ToString(tickers[i]);
/*solium-disable-next-line security/no-block-members*/
if (getUintValue(Encoder.getKey("registeredTickers_expiryDate", ticker)) >= now || getTickerStatus(ticker)) {
counter ++;
if (_ownerInTicker(tickers[i])) {
count++;
}
}
bytes32[] memory tempList = new bytes32[](counter);
counter = 0;
bytes32[] memory result = new bytes32[](count);
count = 0;
for (i = 0; i < tickers.length; i++) {
string memory ticker = Util.bytes32ToString(tickers[i]);
/*solium-disable-next-line security/no-block-members*/
if (getUintValue(Encoder.getKey("registeredTickers_expiryDate", ticker)) >= now || getTickerStatus(ticker)) {
tempList[counter] = tickers[i];
counter ++;
if (_ownerInTicker(tickers[i])) {
result[count] = tickers[i];
count++;
}
}
return tempList;
return result;
}

function _ownerInTicker(bytes32 _ticker) internal view returns (bool) {
string memory ticker = Util.bytes32ToString(_ticker);
/*solium-disable-next-line security/no-block-members*/
if (getUintValue(Encoder.getKey("registeredTickers_expiryDate", ticker)) >= now || getBoolValue(Encoder.getKey("registeredTickers_status", ticker))) {
return true;
}
return false;
}

/**
Expand All @@ -54,7 +61,7 @@ contract STRGetter is EternalStorage {
* @notice Returns the list of all tokens
* @dev Intention is that this is called off-chain so block gas limit is not relevant
*/
function getTokens() external view returns(address[] memory) {
function getTokens() public view returns(address[] memory) {
return _getTokens(true, address(0));
}
/**
Expand All @@ -67,38 +74,86 @@ contract STRGetter is EternalStorage {
// This ensures we find tokens, even if their owner has been modified
address[] memory activeUsers = getArrayAddress(Encoder.getKey("activeUsers"));
bytes32[] memory tickers;
address token;
uint256 count = 0;
uint256 i = 0;
uint256 j = 0;
for (i = 0; i < activeUsers.length; i++) {
tickers = getArrayBytes32(Encoder.getKey("userToTickers", activeUsers[i]));
for (j = 0; j < tickers.length; j++) {
token = getAddressValue(Encoder.getKey("tickerToSecurityToken", Util.bytes32ToString(tickers[j])));
if (token != address(0)) {
if (_allTokens || IOwnable(token).owner() == _owner) {
count = count + 1;
}
if (address(0) != _ownerInToken(tickers[j], _allTokens, _owner)) {
count++;
}
}
}
uint256 index = 0;
address[] memory result = new address[](count);
count = 0;
address token;
for (i = 0; i < activeUsers.length; i++) {
tickers = getArrayBytes32(Encoder.getKey("userToTickers", activeUsers[i]));
for (j = 0; j < tickers.length; j++) {
token = getAddressValue(Encoder.getKey("tickerToSecurityToken", Util.bytes32ToString(tickers[j])));
if (token != address(0)) {
if (_allTokens || IOwnable(token).owner() == _owner) {
result[index] = token;
index = index + 1;
}
token = _ownerInToken(tickers[j], _allTokens, _owner);
if (address(0) != token) {
result[count] = token;
count++;
}
}
}
return result;
}

function _ownerInToken(bytes32 _ticker, bool _allTokens, address _owner) internal view returns(address) {
address token = getAddressValue(Encoder.getKey("tickerToSecurityToken", Util.bytes32ToString(_ticker)));
if (token != address(0)) {
if (_allTokens || IOwnable(token).owner() == _owner) {
return token;
}
}
return address(0);
}

/**
* @notice Returns the list of tokens to which the delegate has some access
* @param _delegate is the address for the delegate
* @dev Intention is that this is called off-chain so block gas limit is not relevant
*/
function getTokensByDelegate(address _delegate) external view returns(address[] memory) {
// Loop over all active users, then all associated tickers of those users
// This ensures we find tokens, even if their owner has been modified
address[] memory tokens = getTokens();
uint256 count = 0;
uint256 i = 0;
for (i = 0; i < tokens.length; i++) {
if (_delegateInToken(tokens[i], _delegate)) {
count++;
}
}
address[] memory result = new address[](count);
count = 0;
for (i = 0; i < tokens.length; i++) {
if (_delegateInToken(tokens[i], _delegate)) {
result[count] = tokens[i];
count++;
}
}
return result;
}

function _delegateInToken(address _token, address _delegate) internal view returns(bool) {
uint256 j = 0;
address[] memory permissionManagers;
bool isArchived;
permissionManagers = ISecurityToken(_token).getModulesByType(1);
for (j = 0; j < permissionManagers.length; j++) {
(,,, isArchived,,) = ISecurityToken(_token).getModule(permissionManagers[j]);
if (!isArchived) {
if (IPermissionManager(permissionManagers[j]).checkDelegate(_delegate)) {
return true;
}
}
}
return false;
}

/**
* @notice Returns the owner and timestamp for a given ticker
* @param _ticker is the ticker symbol
Expand Down
Loading

0 comments on commit 3613255

Please sign in to comment.