Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge 2.1 / 2.2 functionality #564

Merged
merged 3 commits into from
Feb 21, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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