pragma solidity 0.5.8;
/**
* @title Proxy
* @dev Gives the possibility to delegate any call to a foreign implementation.
*/
contract Proxy {
/**
* @dev Tells the address of the implementation where every call will be delegated.
* @return address of the implementation to which it will be delegated
*/
function _implementation() internal view returns(address);
/**
* @dev Fallback function.
* Implemented entirely in `_fallback`.
*/
function _fallback() internal {
_delegate(_implementation());
}
/**
* @dev Fallback function allowing to perform a delegatecall to the given implementation.
* This function will return whatever the implementation call returns
*/
function _delegate(address implementation) internal {
/*solium-disable-next-line security/no-inline-assembly*/
assembly {
// Copy msg.data. We take full control of memory in this inline assembly
// block because it will not return to Solidity code. We overwrite the
// Solidity scratch pad at memory position 0.
calldatacopy(0, 0, calldatasize)
// Call the implementation.
// out and outsize are 0 because we don't know the size yet.
let result := delegatecall(gas, implementation, 0, calldatasize, 0, 0)
// Copy the returned data.
returndatacopy(0, 0, returndatasize)
switch result
// delegatecall returns 0 on error.
case 0 { revert(0, returndatasize) }
default { return(0, returndatasize) }
}
}
function() external payable {
_fallback();
}
}
/**
* Utility library of inline functions on addresses
*/
library Address {
/**
* Returns whether the target address is a contract
* @dev This function will return false if invoked during the constructor of a contract,
* as the code is not actually created until after the constructor finishes.
* @param account address of the account to check
* @return whether the target address is a contract
*/
function isContract(address account) internal view returns (bool) {
uint256 size;
// XXX Currently there is no better way to check if there is a contract in an address
// than to check the size of the code at that address.
// See https://ethereum.stackexchange.com/a/14016/36603
// for more details about how this works.
// TODO Check this again before the Serenity release, because all addresses will be
// contracts then.
// solhint-disable-next-line no-inline-assembly
assembly { size := extcodesize(account) }
return size > 0;
}
}
/**
* @title UpgradeabilityProxy
* @dev This contract represents a proxy where the implementation address to which it will delegate can be upgraded
*/
contract UpgradeabilityProxy is Proxy {
// Version name of the current implementation
string internal __version;
// Address of the current implementation
address internal __implementation;
/**
* @dev This event will be emitted every time the implementation gets upgraded
* @param _newVersion representing the version name of the upgraded implementation
* @param _newImplementation representing the address of the upgraded implementation
*/
event Upgraded(string _newVersion, address indexed _newImplementation);
/**
* @dev Upgrades the implementation address
* @param _newVersion representing the version name of the new implementation to be set
* @param _newImplementation representing the address of the new implementation to be set
*/
function _upgradeTo(string memory _newVersion, address _newImplementation) internal {
require(
__implementation != _newImplementation && _newImplementation != address(0),
"Old address is not allowed and implementation address should not be 0x"
);
require(Address.isContract(_newImplementation), "Cannot set a proxy implementation to a non-contract address");
require(bytes(_newVersion).length > 0, "Version should not be empty string");
require(keccak256(abi.encodePacked(__version)) != keccak256(abi.encodePacked(_newVersion)), "New version equals to current");
__version = _newVersion;
__implementation = _newImplementation;
emit Upgraded(_newVersion, _newImplementation);
}
}
/**
* @title OwnedUpgradeabilityProxy
* @dev This contract combines an upgradeability proxy with basic authorization control functionalities
*/
contract OwnedUpgradeabilityProxy is UpgradeabilityProxy {
// Owner of the contract
address private __upgradeabilityOwner;
/**
* @dev Event to show ownership has been transferred
* @param _previousOwner representing the address of the previous owner
* @param _newOwner representing the address of the new owner
*/
event ProxyOwnershipTransferred(address _previousOwner, address _newOwner);
/**
* @dev Throws if called by any account other than the owner.
*/
modifier ifOwner() {
if (msg.sender == _upgradeabilityOwner()) {
_;
} else {
_fallback();
}
}
/**
* @dev the constructor sets the original owner of the contract to the sender account.
*/
constructor() public {
_setUpgradeabilityOwner(msg.sender);
}
/**
* @dev Tells the address of the owner
* @return the address of the owner
*/
function _upgradeabilityOwner() internal view returns(address) {
return __upgradeabilityOwner;
}
/**
* @dev Sets the address of the owner
*/
function _setUpgradeabilityOwner(address _newUpgradeabilityOwner) internal {
require(_newUpgradeabilityOwner != address(0), "Address should not be 0x");
__upgradeabilityOwner = _newUpgradeabilityOwner;
}
/**
* @notice Internal function to provide the address of the implementation contract
*/
function _implementation() internal view returns(address) {
return __implementation;
}
/**
* @dev Tells the address of the proxy owner
* @return the address of the proxy owner
*/
function proxyOwner() external ifOwner returns(address) {
return _upgradeabilityOwner();
}
/**
* @dev Tells the version name of the current implementation
* @return string representing the name of the current version
*/
function version() external ifOwner returns(string memory) {
return __version;
}
/**
* @dev Tells the address of the current implementation
* @return address of the current implementation
*/
function implementation() external ifOwner returns(address) {
return _implementation();
}
/**
* @dev Allows the current owner to transfer control of the contract to a newOwner.
* @param _newOwner The address to transfer ownership to.
*/
function transferProxyOwnership(address _newOwner) external ifOwner {
require(_newOwner != address(0), "Address should not be 0x");
emit ProxyOwnershipTransferred(_upgradeabilityOwner(), _newOwner);
_setUpgradeabilityOwner(_newOwner);
}
/**
* @dev Allows the upgradeability owner to upgrade the current version of the proxy.
* @param _newVersion representing the version name of the new implementation to be set.
* @param _newImplementation representing the address of the new implementation to be set.
*/
function upgradeTo(string calldata _newVersion, address _newImplementation) external ifOwner {
_upgradeTo(_newVersion, _newImplementation);
}
/**
* @dev Allows the upgradeability owner to upgrade the current version of the proxy and call the new implementation
* to initialize whatever is needed through a low level call.
* @param _newVersion representing the version name of the new implementation to be set.
* @param _newImplementation representing the address of the new implementation to be set.
* @param _data represents the msg.data to bet sent in the low level call. This parameter may include the function
* signature of the implementation to be called with the needed payload
*/
function upgradeToAndCall(string calldata _newVersion, address _newImplementation, bytes calldata _data) external payable ifOwner {
_upgradeToAndCall(_newVersion, _newImplementation, _data);
}
function _upgradeToAndCall(string memory _newVersion, address _newImplementation, bytes memory _data) internal {
_upgradeTo(_newVersion, _newImplementation);
bool success;
/*solium-disable-next-line security/no-call-value*/
(success, ) = address(this).call.value(msg.value)(_data);
require(success, "Fail in executing the function of implementation contract");
}
}
/**
* @title It holds the storage variables related to ERC20DividendCheckpoint module
*/
contract ERC20DividendCheckpointStorage {
// Mapping to token address for each dividend
mapping(uint256 => address) public dividendTokens;
}
/**
* @title Holds the storage variable for the DividendCheckpoint modules (i.e ERC20, Ether)
* @dev abstract contract
*/
contract DividendCheckpointStorage {
// Address to which reclaimed dividends and withholding tax is sent
address payable public wallet;
uint256 public EXCLUDED_ADDRESS_LIMIT = 150;
struct Dividend {
uint256 checkpointId;
uint256 created; // Time at which the dividend was created
uint256 maturity; // Time after which dividend can be claimed - set to 0 to bypass
uint256 expiry; // Time until which dividend can be claimed - after this time any remaining amount can be withdrawn by issuer -
// set to very high value to bypass
uint256 amount; // Dividend amount in WEI
uint256 claimedAmount; // Amount of dividend claimed so far
uint256 totalSupply; // Total supply at the associated checkpoint (avoids recalculating this)
bool reclaimed; // True if expiry has passed and issuer has reclaimed remaining dividend
uint256 totalWithheld;
uint256 totalWithheldWithdrawn;
mapping (address => bool) claimed; // List of addresses which have claimed dividend
mapping (address => bool) dividendExcluded; // List of addresses which cannot claim dividends
mapping (address => uint256) withheld; // Amount of tax withheld from claim
bytes32 name; // Name/title - used for identification
}
// List of all dividends
Dividend[] public dividends;
// List of addresses which cannot claim dividends
address[] public excluded;
// Mapping from address to withholding tax as a percentage * 10**16
mapping (address => uint256) public withholdingTax;
// Total amount of ETH withheld per investor
mapping(address => uint256) public investorWithheld;
}
/**
* @title Utility contract to allow pausing and unpausing of certain functions
*/
contract Pausable {
event Pause(address account);
event Unpause(address account);
bool public paused = false;
/**
* @notice Modifier to make a function callable only when the contract is not paused.
*/
modifier whenNotPaused() {
require(!paused, "Contract is paused");
_;
}
/**
* @notice Modifier to make a function callable only when the contract is paused.
*/
modifier whenPaused() {
require(paused, "Contract is not paused");
_;
}
/**
* @notice Called by the owner to pause, triggers stopped state
*/
function _pause() internal whenNotPaused {
paused = true;
/*solium-disable-next-line security/no-block-members*/
emit Pause(msg.sender);
}
/**
* @notice Called by the owner to unpause, returns to normal state
*/
function _unpause() internal whenPaused {
paused = false;
/*solium-disable-next-line security/no-block-members*/
emit Unpause(msg.sender);
}
}
/**
* @title ERC20 interface
* @dev see https://eips.ethereum.org/EIPS/eip-20
*/
interface IERC20 {
function transfer(address to, uint256 value) external returns (bool);
function approve(address spender, uint256 value) external returns (bool);
function transferFrom(address from, address to, uint256 value) external returns (bool);
function totalSupply() external view returns (uint256);
function balanceOf(address who) external view returns (uint256);
function allowance(address owner, address spender) external view returns (uint256);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
/**
* @title Interface for all security tokens
*/
interface ISecurityToken {
// Standard ERC20 interface
function symbol() external view returns (string memory);
function name() external view returns (string memory);
function decimals() external view returns(uint8);
function totalSupply() external view returns(uint256);
function balanceOf(address owner) external view returns(uint256);
function allowance(address owner, address spender) external view returns(uint256);
function transfer(address to, uint256 value) external returns(bool);
function transferFrom(address from, address to, uint256 value) external returns(bool);
function approve(address spender, uint256 value) external returns(bool);
function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool);
function increaseAllowance(address spender, uint256 addedValue) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @notice Transfers of securities may fail for a number of reasons. So this function will used to understand the
* cause of failure by getting the byte value. Which will be the ESC that follows the EIP 1066. ESC can be mapped
* with a reson string to understand the failure cause, table of Ethereum status code will always reside off-chain
* @param _to address The address which you want to transfer to
* @param _value uint256 the amount of tokens to be transferred
* @param _data The `bytes _data` allows arbitrary data to be submitted alongside the transfer.
* @return byte Ethereum status code (ESC)
* @return bytes32 Application specific reason code
*/
function canTransfer(address _to, uint256 _value, bytes calldata _data) external view returns (byte statusCode, bytes32 reasonCode);
// Emit at the time when module get added
event ModuleAdded(
uint8[] _types,
bytes32 indexed _name,
address indexed _moduleFactory,
address _module,
uint256 _moduleCost,
uint256 _budget,
bytes32 _label,
bool _archived
);
// Emit when the token details get updated
event UpdateTokenDetails(string _oldDetails, string _newDetails);
// Emit when the token name get updated
event UpdateTokenName(string _oldName, string _newName);
// Emit when the granularity get changed
event GranularityChanged(uint256 _oldGranularity, uint256 _newGranularity);
// Emit when is permanently frozen by the issuer
event FreezeIssuance();
// Emit when transfers are frozen or unfrozen
event FreezeTransfers(bool _status);
// Emit when new checkpoint created
event CheckpointCreated(uint256 indexed _checkpointId, uint256 _investorLength);
// Events to log controller actions
event SetController(address indexed _oldController, address indexed _newController);
//Event emit when the global treasury wallet address get changed
event TreasuryWalletChanged(address _oldTreasuryWallet, address _newTreasuryWallet);
event DisableController();
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.
// Transfer Events
event TransferByPartition(
bytes32 indexed _fromPartition,
address _operator,
address indexed _from,
address indexed _to,
uint256 _value,
bytes _data,
bytes _operatorData
);
// Operator Events
event AuthorizedOperator(address indexed operator, address indexed tokenHolder);
event RevokedOperator(address indexed operator, address indexed tokenHolder);
event AuthorizedOperatorByPartition(bytes32 indexed partition, address indexed operator, address indexed tokenHolder);
event RevokedOperatorByPartition(bytes32 indexed partition, address indexed operator, address indexed tokenHolder);
// Issuance / Redemption Events
event IssuedByPartition(bytes32 indexed partition, address indexed to, uint256 value, bytes data);
event RedeemedByPartition(bytes32 indexed partition, address indexed operator, address indexed from, uint256 value, bytes data, bytes operatorData);
// Document Events
event DocumentRemoved(bytes32 indexed _name, string _uri, bytes32 _documentHash);
event DocumentUpdated(bytes32 indexed _name, string _uri, bytes32 _documentHash);
// Controller Events
event ControllerTransfer(
address _controller,
address indexed _from,
address indexed _to,
uint256 _value,
bytes _data,
bytes _operatorData
);
event ControllerRedemption(
address _controller,
address indexed _tokenHolder,
uint256 _value,
bytes _data,
bytes _operatorData
);
// Issuance / Redemption Events
event Issued(address indexed _operator, address indexed _to, uint256 _value, bytes _data);
event Redeemed(address indexed _operator, address indexed _from, uint256 _value, bytes _data);
/**
* @notice Initialization function
* @dev Expected to be called atomically with the proxy being created, by the owner of the token
* @dev Can only be called once
*/
function initialize(address _getterDelegate) external;
/**
* @notice The standard provides an on-chain function to determine whether a transfer will succeed,
* and return details indicating the reason if the transfer is not valid.
* @param _from The address from whom the tokens get transferred.
* @param _to The address to which to transfer tokens to.
* @param _partition The partition from which to transfer tokens
* @param _value The amount of tokens to transfer from `_partition`
* @param _data Additional data attached to the transfer of tokens
* @return ESC (Ethereum Status Code) following the EIP-1066 standard
* @return Application specific reason codes with additional details
* @return The partition to which the transferred tokens were allocated for the _to address
*/
function canTransferByPartition(
address _from,
address _to,
bytes32 _partition,
uint256 _value,
bytes calldata _data
)
external
view
returns (byte statusCode, bytes32 reasonCode, bytes32 partition);
/**
* @notice Transfers of securities may fail for a number of reasons. So this function will used to understand the
* cause of failure by getting the byte value. Which will be the ESC that follows the EIP 1066. ESC can be mapped
* with a reson string to understand the failure cause, table of Ethereum status code will always reside off-chain
* @param _from address The address which you want to send tokens from
* @param _to address The address which you want to transfer to
* @param _value uint256 the amount of tokens to be transferred
* @param _data The `bytes _data` allows arbitrary data to be submitted alongside the transfer.
* @return byte Ethereum status code (ESC)
* @return bytes32 Application specific reason code
*/
function canTransferFrom(address _from, address _to, uint256 _value, bytes calldata _data) external view returns (byte statusCode, bytes32 reasonCode);
/**
* @notice Used to attach a new document to the contract, or update the URI or hash of an existing attached document
* @dev Can only be executed by the owner of the contract.
* @param _name Name of the document. It should be unique always
* @param _uri Off-chain uri of the document from where it is accessible to investors/advisors to read.
* @param _documentHash hash (of the contents) of the document.
*/
function setDocument(bytes32 _name, string calldata _uri, bytes32 _documentHash) external;
/**
* @notice Used to remove an existing document from the contract by giving the name of the document.
* @dev Can only be executed by the owner of the contract.
* @param _name Name of the document. It should be unique always
*/
function removeDocument(bytes32 _name) external;
/**
* @notice Used to return the details of a document with a known name (`bytes32`).
* @param _name Name of the document
* @return string The URI associated with the document.
* @return bytes32 The hash (of the contents) of the document.
* @return uint256 the timestamp at which the document was last modified.
*/
function getDocument(bytes32 _name) external view returns (string memory documentUri, bytes32 documentHash, uint256 documentTime);
/**
* @notice Used to retrieve a full list of documents attached to the smart contract.
* @return bytes32 List of all documents names present in the contract.
*/
function getAllDocuments() external view returns (bytes32[] memory documentNames);
/**
* @notice In order to provide transparency over whether `controllerTransfer` / `controllerRedeem` are useable
* or not `isControllable` function will be used.
* @dev If `isControllable` returns `false` then it always return `false` and
* `controllerTransfer` / `controllerRedeem` will always revert.
* @return bool `true` when controller address is non-zero otherwise return `false`.
*/
function isControllable() external view returns (bool controlled);
/**
* @notice Checks if an address is a module of certain type
* @param _module Address to check
* @param _type type to check against
*/
function isModule(address _module, uint8 _type) external view returns(bool isValid);
/**
* @notice This function must be called to increase the total supply (Corresponds to mint function of ERC20).
* @dev It only be called by the token issuer or the operator defined by the issuer. ERC1594 doesn't have
* have the any logic related to operator but its superset ERC1400 have the operator logic and this function
* is allowed to call by the operator.
* @param _tokenHolder The account that will receive the created tokens (account should be whitelisted or KYCed).
* @param _value The amount of tokens need to be issued
* @param _data The `bytes _data` allows arbitrary data to be submitted alongside the transfer.
*/
function issue(address _tokenHolder, uint256 _value, bytes calldata _data) external;
/**
* @notice issue new tokens and assigns them to the target _tokenHolder.
* @dev Can only be called by the issuer or STO attached to the token.
* @param _tokenHolders A list of addresses to whom the minted tokens will be dilivered
* @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;
/**
* @notice Increases totalSupply and the corresponding amount of the specified owners partition
* @param _partition The partition to allocate the increase in balance
* @param _tokenHolder The token holder whose balance should be increased
* @param _value The amount by which to increase the balance
* @param _data Additional data attached to the minting of tokens
*/
function issueByPartition(bytes32 _partition, address _tokenHolder, uint256 _value, bytes calldata _data) external;
/**
* @notice Decreases totalSupply and the corresponding amount of the specified partition of msg.sender
* @param _partition The partition to allocate the decrease in balance
* @param _value The amount by which to decrease the balance
* @param _data Additional data attached to the burning of tokens
*/
function redeemByPartition(bytes32 _partition, uint256 _value, bytes calldata _data) external;
/**
* @notice This function redeem an amount of the token of a msg.sender. For doing so msg.sender may incentivize
* using different ways that could be implemented with in the `redeem` function definition. But those implementations
* are out of the scope of the ERC1594.
* @param _value The amount of tokens need to be redeemed
* @param _data The `bytes _data` it can be used in the token contract to authenticate the redemption.
*/
function redeem(uint256 _value, bytes calldata _data) external;
/**
* @notice This function redeem an amount of the token of a msg.sender. For doing so msg.sender may incentivize
* using different ways that could be implemented with in the `redeem` function definition. But those implementations
* are out of the scope of the ERC1594.
* @dev It is analogy to `transferFrom`
* @param _tokenHolder The account whose tokens gets redeemed.
* @param _value The amount of tokens need to be redeemed
* @param _data The `bytes _data` it can be used in the token contract to authenticate the redemption.
*/
function redeemFrom(address _tokenHolder, uint256 _value, bytes calldata _data) external;
/**
* @notice Decreases totalSupply and the corresponding amount of the specified partition of tokenHolder
* @dev This function can only be called by the authorised operator.
* @param _partition The partition to allocate the decrease in balance.
* @param _tokenHolder The token holder whose balance should be decreased
* @param _value The amount by which to decrease the balance
* @param _data Additional data attached to the burning of tokens
* @param _operatorData Additional data attached to the transfer of tokens by the operator
*/
function operatorRedeemByPartition(
bytes32 _partition,
address _tokenHolder,
uint256 _value,
bytes calldata _data,
bytes calldata _operatorData
) external;
/**
* @notice Validate permissions with PermissionManager if it exists, If no Permission return false
* @dev Note that IModule withPerm will allow ST owner all permissions anyway
* @dev this allows individual modules to override this logic if needed (to not allow ST owner all permissions)
* @param _delegate address of delegate
* @param _module address of PermissionManager module
* @param _perm the permissions
* @return success
*/
function checkPermission(address _delegate, address _module, bytes32 _perm) external view returns(bool hasPermission);
/**
* @notice Returns module list for a module type
* @param _module Address of the module
* @return bytes32 Name
* @return address Module address
* @return address Module factory address
* @return bool Module archived
* @return uint8 Array of module types
* @return bytes32 Module label
*/
function getModule(address _module) external view returns (bytes32 moduleName, address moduleAddress, address factoryAddress, bool isArchived, uint8[] memory moduleTypes, bytes32 moduleLabel);
/**
* @notice Returns module list for a module name
* @param _name Name of the module
* @return address[] List of modules with this name
*/
function getModulesByName(bytes32 _name) external view returns(address[] memory modules);
/**
* @notice Returns module list for a module type
* @param _type Type of the module
* @return address[] List of modules with this type
*/
function getModulesByType(uint8 _type) external view returns(address[] memory modules);
/**
* @notice use to return the global treasury wallet
*/
function getTreasuryWallet() external view returns(address treasuryWallet);
/**
* @notice Queries totalSupply at a specified checkpoint
* @param _checkpointId Checkpoint ID to query as of
*/
function totalSupplyAt(uint256 _checkpointId) external view returns(uint256 supply);
/**
* @notice Queries balance at a specified checkpoint
* @param _investor Investor to query balance for
* @param _checkpointId Checkpoint ID to query as of
*/
function balanceOfAt(address _investor, uint256 _checkpointId) external view returns(uint256 balance);
/**
* @notice Creates a checkpoint that can be used to query historical balances / totalSuppy
*/
function createCheckpoint() external returns(uint256 checkpointId);
/**
* @notice Gets list of times that checkpoints were created
* @return List of checkpoint times
*/
function getCheckpointTimes() external view returns(uint256[] memory checkpointTimes);
/**
* @notice returns an array of investors
* NB - this length may differ from investorCount as it contains all investors that ever held tokens
* @return list of addresses
*/
function getInvestors() external view returns(address[] memory investors);
/**
* @notice returns an array of investors at a given checkpoint
* NB - this length may differ from investorCount as it contains all investors that ever held tokens
* @param _checkpointId Checkpoint id at which investor list is to be populated
* @return list of investors
*/
function getInvestorsAt(uint256 _checkpointId) external view returns(address[] memory investors);
/**
* @notice returns an array of investors with non zero balance at a given checkpoint
* @param _checkpointId Checkpoint id at which investor list is to be populated
* @param _start Position of investor to start iteration from
* @param _end Position of investor to stop iteration at
* @return list of investors
*/
function getInvestorsSubsetAt(uint256 _checkpointId, uint256 _start, uint256 _end) external view returns(address[] memory investors);
/**
* @notice generates subset of investors
* NB - can be used in batches if investor list is large
* @param _start Position of investor to start iteration from
* @param _end Position of investor to stop iteration at
* @return list of investors
*/
function iterateInvestors(uint256 _start, uint256 _end) external view returns(address[] memory investors);
/**
* @notice Gets current checkpoint ID
* @return Id
*/
function currentCheckpointId() external view returns(uint256 checkpointId);
/**
* @notice Determines whether `_operator` is an operator for all partitions of `_tokenHolder`
* @param _operator The operator to check
* @param _tokenHolder The token holder to check
* @return Whether the `_operator` is an operator for all partitions of `_tokenHolder`
*/
function isOperator(address _operator, address _tokenHolder) external view returns (bool isValid);
/**
* @notice Determines whether `_operator` is an operator for a specified partition of `_tokenHolder`
* @param _partition The partition to check
* @param _operator The operator to check
* @param _tokenHolder The token holder to check
* @return Whether the `_operator` is an operator for a specified partition of `_tokenHolder`
*/
function isOperatorForPartition(bytes32 _partition, address _operator, address _tokenHolder) external view returns (bool isValid);
/**
* @notice Return all partitions
* @param _tokenHolder Whom balance need to queried
* @return List of partitions
*/
function partitionsOf(address _tokenHolder) external view returns (bytes32[] memory partitions);
/**
* @notice Gets data store address
* @return data store address
*/
function dataStore() external view returns (address dataStoreAddress);
/**
* @notice Allows owner to change data store
* @param _dataStore Address of the token data store
*/
function changeDataStore(address _dataStore) external;
/**
* @notice Allows to change the treasury wallet address
* @param _wallet Ethereum address of the treasury wallet
*/
function changeTreasuryWallet(address _wallet) external;
/**
* @notice Allows the owner to withdraw unspent POLY stored by them on the ST or any ERC20 token.
* @dev Owner can transfer POLY to the ST which will be used to pay for modules that require a POLY fee.
* @param _tokenContract Address of the ERC20Basic compliance token
* @param _value Amount of POLY to withdraw
*/
function withdrawERC20(address _tokenContract, uint256 _value) external;
/**
* @notice Allows owner to increase/decrease POLY approval of one of the modules
* @param _module Module address
* @param _change Change in allowance
* @param _increase True if budget has to be increased, false if decrease
*/
function changeModuleBudget(address _module, uint256 _change, bool _increase) external;
/**
* @notice Changes the tokenDetails
* @param _newTokenDetails New token details
*/
function updateTokenDetails(string calldata _newTokenDetails) external;
/**
* @notice Allows owner to change token name
* @param _name new name of the token
*/
function changeName(string calldata _name) external;
/**
* @notice Allows the owner to change token granularity
* @param _granularity Granularity level of the token
*/
function changeGranularity(uint256 _granularity) external;
/**
* @notice Freezes all the transfers
*/
function freezeTransfers() external;
/**
* @notice Un-freezes all the transfers
*/
function unfreezeTransfers() external;
/**
* @notice Permanently freeze issuance of this security token.
* @dev It MUST NOT be possible to increase `totalSuppy` after this function is called.
*/
function freezeIssuance(bytes calldata _signature) external;
/**
* @notice Attachs a module to the SecurityToken
* @dev E.G.: On deployment (through the STR) ST gets a TransferManager module attached to it
* @dev to control restrictions on transfers.
* @param _moduleFactory is the address of the module factory to be added
* @param _data is data packed into bytes used to further configure the module (See STO usage)
* @param _maxCost max amount of POLY willing to pay to the module.
* @param _budget max amount of ongoing POLY willing to assign to the module.
* @param _label custom module label.
* @param _archived whether to add the module as an archived module
*/
function addModuleWithLabel(
address _moduleFactory,
bytes calldata _data,
uint256 _maxCost,
uint256 _budget,
bytes32 _label,
bool _archived
) external;
/**
* @notice Function used to attach a module to the security token
* @dev E.G.: On deployment (through the STR) ST gets a TransferManager module attached to it
* @dev to control restrictions on transfers.
* @dev You are allowed to add a new moduleType if:
* @dev - there is no existing module of that type yet added
* @dev - the last member of the module list is replacable
* @param _moduleFactory is the address of the module factory to be added
* @param _data is data packed into bytes used to further configure the module (See STO usage)
* @param _maxCost max amount of POLY willing to pay to module. (WIP)
* @param _budget max amount of ongoing POLY willing to assign to the module.
* @param _archived whether to add the module as an archived module
*/
function addModule(address _moduleFactory, bytes calldata _data, uint256 _maxCost, uint256 _budget, bool _archived) external;
/**
* @notice Archives a module attached to the SecurityToken
* @param _module address of module to archive
*/
function archiveModule(address _module) external;
/**
* @notice Unarchives a module attached to the SecurityToken
* @param _module address of module to unarchive
*/
function unarchiveModule(address _module) external;
/**
* @notice Removes a module attached to the SecurityToken
* @param _module address of module to archive
*/
function removeModule(address _module) external;
/**
* @notice Used by the issuer to set the controller addresses
* @param _controller address of the controller
*/
function setController(address _controller) external;
/**
* @notice This function allows an authorised address to transfer tokens between any two token holders.
* The transfer must still respect the balances of the token holders (so the transfer must be for at most
* `balanceOf(_from)` tokens) and potentially also need to respect other transfer restrictions.
* @dev This function can only be executed by the `controller` address.
* @param _from Address The address which you want to send tokens from
* @param _to Address The address which you want to transfer to
* @param _value uint256 the amount of tokens to be transferred
* @param _data data to validate the transfer. (It is not used in this reference implementation
* because use of `_data` parameter is implementation specific).
* @param _operatorData data attached to the transfer by controller to emit in event. (It is more like a reason string
* for calling this function (aka force transfer) which provides the transparency on-chain).
*/
function controllerTransfer(address _from, address _to, uint256 _value, bytes calldata _data, bytes calldata _operatorData) external;
/**
* @notice This function allows an authorised address to redeem tokens for any token holder.
* The redemption must still respect the balances of the token holder (so the redemption must be for at most
* `balanceOf(_tokenHolder)` tokens) and potentially also need to respect other transfer restrictions.
* @dev This function can only be executed by the `controller` address.
* @param _tokenHolder The account whose tokens will be redeemed.
* @param _value uint256 the amount of tokens need to be redeemed.
* @param _data data to validate the transfer. (It is not used in this reference implementation
* because use of `_data` parameter is implementation specific).
* @param _operatorData data attached to the transfer by controller to emit in event. (It is more like a reason string
* for calling this function (aka force transfer) which provides the transparency on-chain).
*/
function controllerRedeem(address _tokenHolder, uint256 _value, bytes calldata _data, bytes calldata _operatorData) external;
/**
* @notice Used by the issuer to permanently disable controller functionality
* @dev enabled via feature switch "disableControllerAllowed"
*/
function disableController(bytes calldata _signature) external;
/**
* @notice Used to get the version of the securityToken
*/
function getVersion() external view returns(uint8[] memory version);
/**
* @notice Gets the investor count
*/
function getInvestorCount() external view returns(uint256 investorCount);
/**
* @notice Gets the holder count (investors with non zero balance)
*/
function holderCount() external view returns(uint256 count);
/**
* @notice Overloaded version of the transfer function
* @param _to receiver of transfer
* @param _value value of transfer
* @param _data data to indicate validation
* @return bool success
*/
function transferWithData(address _to, uint256 _value, bytes calldata _data) external;
/**
* @notice Overloaded version of the transferFrom function
* @param _from sender of transfer
* @param _to receiver of transfer
* @param _value value of transfer
* @param _data data to indicate validation
* @return bool success
*/
function transferFromWithData(address _from, address _to, uint256 _value, bytes calldata _data) external;
/**
* @notice Transfers the ownership of tokens from a specified partition from one address to another address
* @param _partition The partition from which to transfer tokens
* @param _to The address to which to transfer tokens to
* @param _value The amount of tokens to transfer from `_partition`
* @param _data Additional data attached to the transfer of tokens
* @return The partition to which the transferred tokens were allocated for the _to address
*/
function transferByPartition(bytes32 _partition, address _to, uint256 _value, bytes calldata _data) external returns (bytes32 partition);
/**
* @notice Get the balance according to the provided partitions
* @param _partition Partition which differentiate the tokens.
* @param _tokenHolder Whom balance need to queried
* @return Amount of tokens as per the given partitions
*/
function balanceOfByPartition(bytes32 _partition, address _tokenHolder) external view returns(uint256 balance);
/**
* @notice Provides the granularity of the token
* @return uint256
*/
function granularity() external view returns(uint256 granularityAmount);
/**
* @notice Provides the address of the polymathRegistry
* @return address
*/
function polymathRegistry() external view returns(address registryAddress);
/**
* @notice Upgrades a module attached to the SecurityToken
* @param _module address of module to archive
*/
function upgradeModule(address _module) external;
/**
* @notice Upgrades security token
*/
function upgradeToken() external;
/**
* @notice A security token issuer can specify that issuance has finished for the token
* (i.e. no new tokens can be minted or issued).
* @dev If a token returns FALSE for `isIssuable()` then it MUST always return FALSE in the future.
* If a token returns FALSE for `isIssuable()` then it MUST never allow additional tokens to be issued.
* @return bool `true` signifies the minting is allowed. While `false` denotes the end of minting
*/
function isIssuable() external view returns (bool issuable);
/**
* @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) external;
/**
* @notice Revokes authorisation of an operator previously given 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 de-authorised
*/
function revokeOperator(address _operator) external;
/**
* @notice Authorises an operator for a given partition of `msg.sender`
* @param _partition The partition to which the operator is authorised
* @param _operator An address which is being authorised
*/
function authorizeOperatorByPartition(bytes32 _partition, address _operator) external;
/**
* @notice Revokes authorisation of an operator previously given for a specified partition of `msg.sender`
* @param _partition The partition to which the operator is de-authorised
* @param _operator An address which is being de-authorised
*/
function revokeOperatorByPartition(bytes32 _partition, address _operator) external;
/**
* @notice Transfers the ownership of tokens from a specified partition from one address to another address
* @param _partition The partition from which to transfer tokens.
* @param _from The address from which to transfer tokens from
* @param _to The address to which to transfer tokens to
* @param _value The amount of tokens to transfer from `_partition`
* @param _data Additional data attached to the transfer of tokens
* @param _operatorData Additional data attached to the transfer of tokens by the operator
* @return The partition to which the transferred tokens were allocated for the _to address
*/
function operatorTransferByPartition(
bytes32 _partition,
address _from,
address _to,
uint256 _value,
bytes calldata _data,
bytes calldata _operatorData
)
external
returns (bytes32 partition);
/*
* @notice Returns if transfers are currently frozen or not
*/
function transfersFrozen() external view returns (bool isFrozen);
/**
* @dev Allows the current owner to transfer control of the contract to a newOwner.
* @param newOwner The address to transfer ownership to.
*/
function transferOwnership(address newOwner) external;
/**
* @return true if `msg.sender` is the owner of the contract.
*/
function isOwner() external view returns (bool);
/**
* @return the address of the owner.
*/
function owner() external view returns (address ownerAddress);
function controller() external view returns(address controllerAddress);
function moduleRegistry() external view returns(address moduleRegistryAddress);
function securityTokenRegistry() external view returns(address securityTokenRegistryAddress);
function polyToken() external view returns(address polyTokenAddress);
function tokenFactory() external view returns(address tokenFactoryAddress);
function getterDelegate() external view returns(address delegate);
function controllerDisabled() external view returns(bool isDisabled);
function initialized() external view returns(bool isInitialized);
function tokenDetails() external view returns(string memory details);
function updateFromRegistry() external;
}
/**
* @title Storage for Module contract
* @notice Contract is abstract
*/
contract ModuleStorage {
address public factory;
ISecurityToken public securityToken;
// Permission flag
bytes32 public constant ADMIN = "ADMIN";
bytes32 public constant OPERATOR = "OPERATOR";
bytes32 internal constant TREASURY = 0xaae8817359f3dcb67d050f44f3e49f982e0359d90ca4b5f18569926304aaece6; // keccak256(abi.encodePacked("TREASURY_WALLET"))
IERC20 public polyToken;
/**
* @notice Constructor
* @param _securityToken Address of the security token
* @param _polyAddress Address of the polytoken
*/
constructor(address _securityToken, address _polyAddress) public {
securityToken = ISecurityToken(_securityToken);
factory = msg.sender;
polyToken = IERC20(_polyAddress);
}
}
/**
* @title Transfer Manager module for core transfer validation functionality
*/
contract ERC20DividendCheckpointProxy is ERC20DividendCheckpointStorage, DividendCheckpointStorage, ModuleStorage, Pausable, OwnedUpgradeabilityProxy {
/**
* @notice Constructor
* @param _securityToken Address of the security token
* @param _polyAddress Address of the polytoken
* @param _implementation representing the address of the new implementation to be set
*/
constructor(
string memory _version,
address _securityToken,
address _polyAddress,
address _implementation
)
public
ModuleStorage(_securityToken, _polyAddress)
{
require(_implementation != address(0), "Implementation address should not be 0x");
_upgradeTo(_version, _implementation);
}
}
/**
* @title Transfer Manager module for core transfer validation functionality
*/
contract EtherDividendCheckpointProxy is DividendCheckpointStorage, ModuleStorage, Pausable, OwnedUpgradeabilityProxy {
/**
* @notice Constructor
* @param _securityToken Address of the security token
* @param _polyAddress Address of the polytoken
* @param _implementation representing the address of the new implementation to be set
*/
constructor (
string memory _version,
address _securityToken,
address _polyAddress,
address _implementation
)
public
ModuleStorage(_securityToken, _polyAddress)
{
require(_implementation != address(0), "Implementation address should not be 0x");
_upgradeTo(_version, _implementation);
}
}
contract PLCRVotingCheckpointStorage {
enum Stage { PREP, COMMIT, REVEAL, RESOLVED }
struct Ballot {
uint256 checkpointId; // Checkpoint At which ballot created
uint256 quorum; // Should be a multiple of 10 ** 16
uint64 commitDuration; // no. of seconds the commit stage will live
uint64 revealDuration; // no. of seconds the reveal stage will live
uint64 startTime; // Timestamp at which ballot will come into effect
uint24 totalProposals; // Count of proposals allowed for a given ballot
uint32 totalVoters; // Count of voters who vote for the given ballot
bool isActive; // flag used to turn off/on the ballot
mapping(uint256 => uint256) proposalToVotes; // Mapping for proposal to total weight collected by the proposal
mapping(address => Vote) investorToProposal; // mapping for storing vote details of a voter
mapping(address => bool) exemptedVoters; // Mapping for blacklist voters
}
struct Vote {
uint256 voteOption;
bytes32 secretVote;
}
Ballot[] ballots;
}
contract VotingCheckpointStorage {
mapping(address => uint256) defaultExemptIndex;
address[] defaultExemptedVoters;
}
/**
* @title Voting module for governance
*/
contract PLCRVotingCheckpointProxy is PLCRVotingCheckpointStorage, VotingCheckpointStorage, ModuleStorage, Pausable, OwnedUpgradeabilityProxy {
/**
* @notice Constructor
* @param _securityToken Address of the security token
* @param _polyAddress Address of the polytoken
* @param _implementation representing the address of the new implementation to be set
*/
constructor(
string memory _version,
address _securityToken,
address _polyAddress,
address _implementation
)
public
ModuleStorage(_securityToken, _polyAddress)
{
require(_implementation != address(0), "Implementation address should not be 0x");
_upgradeTo(_version, _implementation);
}
}
contract WeightedVoteCheckpointStorage {
struct Ballot {
uint256 checkpointId; // Checkpoint At which ballot created
uint256 quorum; // Should be a multiple of 10 ** 16
uint64 startTime; // Timestamp at which ballot will come into effect
uint64 endTime; // Timestamp at which ballot will no more into effect
uint64 totalProposals; // Count of proposals allowed for a given ballot
uint56 totalVoters; // Count of voters who vote for the given ballot
bool isActive; // flag used to turn off/on the ballot
mapping(uint256 => uint256) proposalToVotes; // Mapping for proposal to total weight collected by the proposal
mapping(address => uint256) investorToProposal; // mapping for storing vote details of a voter
mapping(address => bool) exemptedVoters; // Mapping for blacklist voters
}
Ballot[] ballots;
}
/**
* @title Voting module for governance
*/
contract WeightedVoteCheckpointProxy is WeightedVoteCheckpointStorage, VotingCheckpointStorage, ModuleStorage, Pausable, OwnedUpgradeabilityProxy {
/**
* @notice Constructor
* @param _securityToken Address of the security token
* @param _polyAddress Address of the polytoken
* @param _implementation representing the address of the new implementation to be set
*/
constructor(
string memory _version,
address _securityToken,
address _polyAddress,
address _implementation
)
public
ModuleStorage(_securityToken, _polyAddress)
{
require(_implementation != address(0), "Implementation address should not be 0x");
_upgradeTo(_version, _implementation);
}
}
/**
* @title Helps contracts guard against reentrancy attacks.
* @author Remco Bloemen <remco@2π.com>, Eenae <alexey@mixbytes.io>
* @dev If you mark a function `nonReentrant`, you should also
* mark it `external`.
*/
contract ReentrancyGuard {
/// @dev counter to allow mutex lock with only one SSTORE operation
uint256 private _guardCounter;
constructor () internal {
// The counter starts at one to prevent changing it from zero to a non-zero
// value, which is a more expensive operation.
_guardCounter = 1;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and make it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
_guardCounter += 1;
uint256 localCounter = _guardCounter;
_;
require(localCounter == _guardCounter);
}
}
/**
* @title Contract used to store layout for the GeneralPermissionManager storage
*/
contract GeneralPermissionManagerStorage {
// Mapping used to hold the permissions on the modules provided to delegate, module add => delegate add => permission bytes32 => bool
mapping (address => mapping (address => mapping (bytes32 => bool))) public perms;
// Mapping hold the delagate details
mapping (address => bytes32) public delegateDetails;
// Array to track all delegates
address[] public allDelegates;
}
/**
* @title GeneralPermissionManager module Proxy
*/
contract GeneralPermissionManagerProxy is GeneralPermissionManagerStorage, ModuleStorage, Pausable, ReentrancyGuard, OwnedUpgradeabilityProxy {
/**
* @notice Constructor
* @param _securityToken Address of the security token
* @param _polyAddress Address of the polytoken
* @param _implementation representing the address of the new implementation to be set
*/
constructor (
string memory _version,
address _securityToken,
address _polyAddress,
address _implementation
)
public
ModuleStorage(_securityToken, _polyAddress)
{
require(
_implementation != address(0),
"Implementation address should not be 0x"
);
_upgradeTo(_version, _implementation);
}
}
/**
* @title Storage layout for the STO contract
*/
contract STOStorage {
bytes32 internal constant INVESTORFLAGS = "INVESTORFLAGS";
mapping (uint8 => bool) public fundRaiseTypes;
mapping (uint8 => uint256) public fundsRaised;
// Start time of the STO
uint256 public startTime;
// End time of the STO
uint256 public endTime;
// Time STO was paused
uint256 public pausedTime;
// Number of individual investors
uint256 public investorCount;
// Address where ETH & POLY funds are delivered
address payable public wallet;
// Final amount of tokens sold
uint256 public totalTokensSold;
}
/**
* @title Contract used to store layout for the CappedSTO storage
*/
contract CappedSTOStorage {
// Determine whether users can invest on behalf of a beneficiary
bool public allowBeneficialInvestments = false;
// How many token units a buyer gets (multiplied by 10^18) per wei / base unit of POLY
// If rate is 10^18, buyer will get 1 token unit for every wei / base unit of poly.
uint256 public rate;
//How many token base units this STO will be allowed to sell to investors
// 1 full token = 10^decimals_of_token base units
uint256 public cap;
mapping (address => uint256) public investors;
}
/**
* @title CappedSTO module Proxy
*/
contract CappedSTOProxy is CappedSTOStorage, STOStorage, ModuleStorage, Pausable, ReentrancyGuard, OwnedUpgradeabilityProxy {
/**
* @notice Constructor
* @param _securityToken Address of the security token
* @param _polyAddress Address of the polytoken
* @param _implementation representing the address of the new implementation to be set
*/
constructor(
string memory _version,
address _securityToken,
address _polyAddress,
address _implementation
)
public
ModuleStorage(_securityToken, _polyAddress)
{
require(
_implementation != address(0),
"Implementation address should not be 0x"
);
_upgradeTo(_version, _implementation);
}
}
/**
* @title Contract used to store layout for the PreSaleSTO storage
*/
contract PreSaleSTOStorage {
mapping (address => uint256) public investors;
}
/**
* @title PreSaleSTO module Proxy
*/
contract PreSaleSTOProxy is PreSaleSTOStorage, STOStorage, ModuleStorage, Pausable, ReentrancyGuard, OwnedUpgradeabilityProxy {
/**
* @notice Constructor
* @param _securityToken Address of the security token
* @param _polyAddress Address of the polytoken
* @param _implementation representing the address of the new implementation to be set
*/
constructor (string memory _version, address _securityToken, address _polyAddress, address _implementation)
public
ModuleStorage(_securityToken, _polyAddress)
{
require(
_implementation != address(0),
"Implementation address should not be 0x"
);
_upgradeTo(_version, _implementation);
}
}
/**
* @title Contract used to store layout for the USDTieredSTO storage
*/
contract USDTieredSTOStorage {
bytes32 internal constant INVESTORSKEY = 0xdf3a8dd24acdd05addfc6aeffef7574d2de3f844535ec91e8e0f3e45dba96731; //keccak256(abi.encodePacked("INVESTORS"))
/////////////
// Storage //
/////////////
struct Tier {
// NB rates mentioned below are actually price and are used like price in the logic.
// How many token units a buyer gets per USD in this tier (multiplied by 10**18)
uint256 rate;
// How many token units a buyer gets per USD in this tier (multiplied by 10**18) when investing in POLY up to tokensDiscountPoly
uint256 rateDiscountPoly;
// How many tokens are available in this tier (relative to totalSupply)
uint256 tokenTotal;
// How many token units are available in this tier (relative to totalSupply) at the ratePerTierDiscountPoly rate
uint256 tokensDiscountPoly;
// How many tokens have been minted in this tier (relative to totalSupply)
uint256 mintedTotal;
// How many tokens have been minted in this tier (relative to totalSupply) for each fund raise type
mapping(uint8 => uint256) minted;
// How many tokens have been minted in this tier (relative to totalSupply) at discounted POLY rate
uint256 mintedDiscountPoly;
}
mapping(address => uint256) public nonAccreditedLimitUSDOverride;
mapping(bytes32 => mapping(bytes32 => string)) oracleKeys;
// Determine whether users can invest on behalf of a beneficiary
bool public allowBeneficialInvestments;
// Whether or not the STO has been finalized
bool public isFinalized;
// Address of issuer treasury wallet for unsold tokens
address public treasuryWallet;
// List of stable coin addresses
IERC20[] internal usdTokens;
// Current tier
uint256 public currentTier;
// Amount of USD funds raised
uint256 public fundsRaisedUSD;
// Amount of stable coins raised
mapping (address => uint256) public stableCoinsRaised;
// Amount in USD invested by each address
mapping(address => uint256) public investorInvestedUSD;
// Amount in fund raise type invested by each investor
mapping(address => mapping(uint8 => uint256)) public investorInvested;
// List of active stable coin addresses
mapping (address => bool) internal usdTokenEnabled;
// Default limit in USD for non-accredited investors multiplied by 10**18
uint256 public nonAccreditedLimitUSD;
// Minimum investable amount in USD
uint256 public minimumInvestmentUSD;
// Final amount of tokens returned to issuer
uint256 public finalAmountReturned;
// Array of Tiers
Tier[] public tiers;
// Optional custom Oracles.
mapping(bytes32 => mapping(bytes32 => address)) customOracles;
}
/**
* @title USDTiered STO module Proxy
*/
contract USDTieredSTOProxy is USDTieredSTOStorage, STOStorage, ModuleStorage, Pausable, ReentrancyGuard, OwnedUpgradeabilityProxy {
/**
* @notice Constructor
* @param _securityToken Address of the security token
* @param _polyAddress Address of the polytoken
* @param _implementation representing the address of the new implementation to be set
*/
constructor (string memory _version, address _securityToken, address _polyAddress, address _implementation) public ModuleStorage(_securityToken, _polyAddress) {
require(_implementation != address(0), "Implementation address should not be 0x");
_upgradeTo(_version, _implementation);
}
}
/**
* @title Contract used to store layout for the CountTransferManager storage
*/
contract BlacklistTransferManagerStorage {
struct BlacklistsDetails {
uint256 startTime;
uint256 endTime;
uint256 repeatPeriodTime;
}
//hold the different blacklist details corresponds to its name
mapping(bytes32 => BlacklistsDetails) public blacklists;
//hold the different name of blacklist corresponds to a investor
mapping(address => bytes32[]) investorToBlacklist;
//get list of the addresses for a particular blacklist
mapping(bytes32 => address[]) blacklistToInvestor;
//mapping use to store the indexes for different blacklist types for a investor
mapping(address => mapping(bytes32 => uint256)) investorToIndex;
//mapping use to store the indexes for different investor for a blacklist type
mapping(bytes32 => mapping(address => uint256)) blacklistToIndex;
bytes32[] allBlacklists;
}
/**
* @title CountTransferManager module Proxy
*/
contract BlacklistTransferManagerProxy is BlacklistTransferManagerStorage, ModuleStorage, Pausable, OwnedUpgradeabilityProxy {
/**
* @notice Constructor
* @param _securityToken Address of the security token
* @param _polyAddress Address of the polytoken
* @param _implementation representing the address of the new implementation to be set
*/
constructor (
string memory _version,
address _securityToken,
address _polyAddress,
address _implementation
)
public
ModuleStorage(_securityToken, _polyAddress)
{
require(
_implementation != address(0),
"Implementation address should not be 0x"
);
_upgradeTo(_version, _implementation);
}
}
/**
* @title Contract used to store layout for the CountTransferManager storage
*/
contract CountTransferManagerStorage {
// The maximum number of concurrent token holders
uint256 public maxHolderCount;
}
/**
* @title CountTransferManager module Proxy
*/
contract CountTransferManagerProxy is CountTransferManagerStorage, ModuleStorage, Pausable, OwnedUpgradeabilityProxy {
/**
* @notice Constructor
* @param _securityToken Address of the security token
* @param _polyAddress Address of the polytoken
* @param _implementation representing the address of the new implementation to be set
*/
constructor (
string memory _version,
address _securityToken,
address _polyAddress,
address _implementation
)
public
ModuleStorage(_securityToken, _polyAddress)
{
require(
_implementation != address(0),
"Implementation address should not be 0x"
);
_upgradeTo(_version, _implementation);
}
}
/**
* @title Transfer Manager module for core transfer validation functionality
*/
contract GeneralTransferManagerStorage {
bytes32 public constant WHITELIST = "WHITELIST";
bytes32 public constant INVESTORSKEY = 0xdf3a8dd24acdd05addfc6aeffef7574d2de3f844535ec91e8e0f3e45dba96731; //keccak256(abi.encodePacked("INVESTORS"))
bytes32 public constant INVESTORFLAGS = "INVESTORFLAGS";
uint256 internal constant ONE = uint256(1);
enum TransferType { GENERAL, ISSUANCE, REDEMPTION }
//Address from which issuances come
address public issuanceAddress;
// Allows all TimeRestrictions to be offset
struct Defaults {
uint64 canSendAfter;
uint64 canReceiveAfter;
}
// Offset to be applied to all timings (except KYC expiry)
Defaults public defaults;
// Map of used nonces by customer
mapping(address => mapping(uint256 => bool)) public nonceMap;
struct TransferRequirements {
bool fromValidKYC;
bool toValidKYC;
bool fromRestricted;
bool toRestricted;
}
mapping(uint8 => TransferRequirements) public transferRequirements;
// General = 0, Issuance = 1, Redemption = 2
}
/**
* @title Transfer Manager module for core transfer validation functionality
*/
contract GeneralTransferManagerProxy is GeneralTransferManagerStorage, ModuleStorage, Pausable, OwnedUpgradeabilityProxy {
/**
* @notice Constructor
* @param _securityToken Address of the security token
* @param _polyAddress Address of the polytoken
* @param _implementation representing the address of the new implementation to be set
*/
constructor(
string memory _version,
address _securityToken,
address _polyAddress,
address _implementation
)
public
ModuleStorage(_securityToken, _polyAddress)
{
require(_implementation != address(0), "Implementation address should not be 0x");
_upgradeTo(_version, _implementation);
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);
}
}
/**
* @title Wallet for core vesting escrow functionality
*/
contract LockUpTransferManagerStorage {
// a per-user lockup
struct LockUp {
uint256 lockupAmount; // Amount to be locked
uint256 startTime; // when this lockup starts (seconds)
uint256 lockUpPeriodSeconds; // total period of lockup (seconds)
uint256 releaseFrequencySeconds; // how often to release a tranche of tokens (seconds)
}
// mapping use to store the lockup details corresponds to lockup name
mapping (bytes32 => LockUp) public lockups;
// mapping user addresses to an array of lockups name for that user
mapping (address => bytes32[]) internal userToLockups;
// get list of the addresses for a particular lockupName
mapping (bytes32 => address[]) internal lockupToUsers;
// holds lockup index corresponds to user address. userAddress => lockupName => lockupIndex
mapping (address => mapping(bytes32 => uint256)) internal userToLockupIndex;
// holds the user address index corresponds to the lockup. lockupName => userAddress => userIndex
mapping (bytes32 => mapping(address => uint256)) internal lockupToUserIndex;
bytes32[] lockupArray;
}
/**
* @title CountTransferManager module Proxy
*/
contract LockUpTransferManagerProxy is LockUpTransferManagerStorage, ModuleStorage, Pausable, OwnedUpgradeabilityProxy {
/**
* @notice Constructor
* @param _securityToken Address of the security token
* @param _polyAddress Address of the polytoken
* @param _implementation representing the address of the new implementation to be set
*/
constructor (
string memory _version,
address _securityToken,
address _polyAddress,
address _implementation
)
public
ModuleStorage(_securityToken, _polyAddress)
{
require(
_implementation != address(0),
"Implementation address should not be 0x"
);
_upgradeTo(_version, _implementation);
}
}
/**
* @title Contract used to store layout for the ManualApprovalTransferManager storage
*/
contract ManualApprovalTransferManagerStorage {
//Manual approval is an allowance (that has been approved) with an expiry time
struct ManualApproval {
address from;
address to;
uint256 allowance;
uint256 expiryTime;
bytes32 description;
}
mapping (address => mapping (address => uint256)) public approvalIndex;
// An array to track all approvals. It is an unbounded array but it's not a problem as
// it is never looped through in an onchain call. It is defined as an Array instead of mapping
// just to make it easier for users to fetch list of all approvals through constant functions.
ManualApproval[] public approvals;
}
/**
@title ManualApprovalTransferManager module Proxy
*/
contract ManualApprovalTransferManagerProxy is ManualApprovalTransferManagerStorage, ModuleStorage, Pausable, OwnedUpgradeabilityProxy {
/**
* @notice Constructor
* @param _securityToken Address of the security token
* @param _polyAddress Address of the polytoken
* @param _implementation representing the address of the new implementation to be set
*/
constructor (
string memory _version,
address _securityToken,
address _polyAddress,
address _implementation
)
public
ModuleStorage(_securityToken, _polyAddress)
{
require(
_implementation != address(0),
"Implementation address should not be 0x"
);
_upgradeTo(_version, _implementation);
}
}
/**
* @title Contract used to store layout for the PercentageTransferManager storage
*/
contract PercentageTransferManagerStorage {
// Maximum percentage that any holder can have, multiplied by 10**16 - e.g. 20% is 20 * 10**16
uint256 public maxHolderPercentage;
// Ignore transactions which are part of the primary issuance
bool public allowPrimaryIssuance = true;
// Addresses on this list are always able to send / receive tokens
mapping (address => bool) public whitelist;
}
/**
* @title PercentageTransferManager module Proxy
*/
contract PercentageTransferManagerProxy is PercentageTransferManagerStorage, ModuleStorage, Pausable, OwnedUpgradeabilityProxy {
/**
* @notice Constructor
* @param _securityToken Address of the security token
* @param _polyAddress Address of the polytoken
* @param _implementation representing the address of the new implementation to be set
*/
constructor (string memory _version, address _securityToken, address _polyAddress, address _implementation)
public
ModuleStorage(_securityToken, _polyAddress)
{
require(
_implementation != address(0),
"Implementation address should not be 0x"
);
_upgradeTo(_version, _implementation);
}
}
/**
* @title Storage layout for VolumeRestrictionTM
*/
contract VolumeRestrictionTMStorage {
enum RestrictionType { Fixed, Percentage }
enum TypeOfPeriod { MultipleDays, OneDay, Both }
// Store the type of restriction corresponds to token holder address
mapping(address => TypeOfPeriod) holderToRestrictionType;
struct VolumeRestriction {
// If typeOfRestriction is `Percentage` then allowedTokens will be in
// the % (w.r.t to totalSupply) with a multiplier of 10**16 . else it
// will be fixed amount of tokens
uint256 allowedTokens;
uint256 startTime;
uint256 rollingPeriodInDays;
uint256 endTime;
RestrictionType typeOfRestriction;
}
struct IndividualRestrictions {
// Restriction stored corresponds to a particular token holder
mapping(address => VolumeRestriction) individualRestriction;
// Daily restriction stored corresponds to a particular token holder
mapping(address => VolumeRestriction) individualDailyRestriction;
}
// Individual and daily restrictions for investors
IndividualRestrictions individualRestrictions;
struct GlobalRestrictions {
// Global restriction that applies to all token holders
VolumeRestriction defaultRestriction;
// Daily global restriction that applies to all token holders (Total ST traded daily is restricted)
VolumeRestriction defaultDailyRestriction;
}
// Individual and daily restrictions for investors
GlobalRestrictions globalRestrictions;
struct BucketDetails {
uint256 lastTradedDayTime;
uint256 sumOfLastPeriod; // It is the sum of transacted amount within the last rollingPeriodDays
uint256 daysCovered; // No of days covered till (from the startTime of VolumeRestriction)
uint256 dailyLastTradedDayTime;
uint256 lastTradedTimestamp; // It is the timestamp at which last transaction get executed
}
struct BucketData {
// Storing _from => day's timestamp => total amount transact in a day --individual
mapping(address => mapping(uint256 => uint256)) bucket;
// Storing _from => day's timestamp => total amount transact in a day --individual
mapping(address => mapping(uint256 => uint256)) defaultBucket;
// Storing the information that used to validate the transaction
mapping(address => BucketDetails) userToBucket;
// Storing the information related to default restriction
mapping(address => BucketDetails) defaultUserToBucket;
}
BucketData bucketData;
// Hold exempt index
struct Exemptions {
mapping(address => uint256) exemptIndex;
address[] exemptAddresses;
}
Exemptions exemptions;
}
/**
* @title Transfer Manager module for core transfer validation functionality
*/
contract VolumeRestrictionTMProxy is VolumeRestrictionTMStorage, ModuleStorage, Pausable, OwnedUpgradeabilityProxy {
/**
* @notice Constructor
* @param _securityToken Address of the security token
* @param _polyAddress Address of the polytoken
* @param _implementation representing the address of the new implementation to be set
*/
constructor (string memory _version, address _securityToken, address _polyAddress, address _implementation)
public
ModuleStorage(_securityToken, _polyAddress)
{
require(
_implementation != address(0),
"Implementation address should not be 0x"
);
_upgradeTo(_version, _implementation);
}
}
/**
* @title Wallet for core vesting escrow functionality
*/
contract VestingEscrowWalletStorage {
struct Schedule {
// Name of the template
bytes32 templateName;
// Tokens that were already claimed
uint256 claimedTokens;
// Start time of the schedule
uint256 startTime;
}
struct Template {
// Total amount of tokens
uint256 numberOfTokens;
// Schedule duration (How long the schedule will last)
uint256 duration;
// Schedule frequency (It is a cliff time period)
uint256 frequency;
// Index of the template in an array template names
uint256 index;
}
// Number of tokens that are hold by the `this` contract but are unassigned to any schedule
uint256 public unassignedTokens;
// Address of the Treasury wallet. All of the unassigned token will transfer to that address.
address public treasuryWallet;
// List of all beneficiaries who have the schedules running/completed/created
address[] public beneficiaries;
// Flag whether beneficiary has been already added or not
mapping(address => bool) internal beneficiaryAdded;
// Holds schedules array corresponds to the affiliate/employee address
mapping(address => Schedule[]) public schedules;
// Holds template names array corresponds to the affiliate/employee address
mapping(address => bytes32[]) internal userToTemplates;
// Mapping use to store the indexes for different template names for a user.
// affiliate/employee address => template name => index
mapping(address => mapping(bytes32 => uint256)) internal userToTemplateIndex;
// Holds affiliate/employee addresses coressponds to the template name
mapping(bytes32 => address[]) internal templateToUsers;
// Mapping use to store the indexes for different users for a template.
// template name => affiliate/employee address => index
mapping(bytes32 => mapping(address => uint256)) internal templateToUserIndex;
// Store the template details corresponds to the template name
mapping(bytes32 => Template) templates;
// List of all template names
bytes32[] public templateNames;
}
/**
* @title Escrow wallet module for vesting functionality
*/
contract VestingEscrowWalletProxy is VestingEscrowWalletStorage, ModuleStorage, Pausable, OwnedUpgradeabilityProxy {
/**
* @notice Constructor
* @param _securityToken Address of the security token
* @param _polyAddress Address of the polytoken
* @param _implementation representing the address of the new implementation to be set
*/
constructor (string memory _version, address _securityToken, address _polyAddress, address _implementation)
public
ModuleStorage(_securityToken, _polyAddress)
{
require(
_implementation != address(0),
"Implementation address should not be 0x"
);
_upgradeTo(_version, _implementation);
}
}
{
"compilationTarget": {
"GeneralTransferManagerProxy.sol": "GeneralTransferManagerProxy"
},
"evmVersion": "petersburg",
"libraries": {},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"constant":false,"inputs":[],"name":"proxyOwner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"WHITELIST","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ADMIN","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"version","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_newVersion","type":"string"},{"name":"_newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"implementation","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"INVESTORFLAGS","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"polyToken","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newVersion","type":"string"},{"name":"_newImplementation","type":"address"},{"name":"_data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"OPERATOR","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"uint256"}],"name":"nonceMap","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"issuanceAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"securityToken","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"INVESTORSKEY","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint8"}],"name":"transferRequirements","outputs":[{"name":"fromValidKYC","type":"bool"},{"name":"toValidKYC","type":"bool"},{"name":"fromRestricted","type":"bool"},{"name":"toRestricted","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"factory","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"defaults","outputs":[{"name":"canSendAfter","type":"uint64"},{"name":"canReceiveAfter","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newOwner","type":"address"}],"name":"transferProxyOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_version","type":"string"},{"name":"_securityToken","type":"address"},{"name":"_polyAddress","type":"address"},{"name":"_implementation","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_previousOwner","type":"address"},{"indexed":false,"name":"_newOwner","type":"address"}],"name":"ProxyOwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_newVersion","type":"string"},{"indexed":true,"name":"_newImplementation","type":"address"}],"name":"Upgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"account","type":"address"}],"name":"Pause","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"account","type":"address"}],"name":"Unpause","type":"event"}]