Feature Tip: Add private address tag to any address under My Name Tag !
Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
EtherDividendCheckpoint
Compiler Version
v0.5.8+commit.23d335f2
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity)
/**
*Submitted for verification at Etherscan.io on 2019-07-19
*/
pragma solidity 0.5.8;
/**
* @title Interface to be implemented by all checkpoint modules
*/
/*solium-disable-next-line no-empty-blocks*/
interface ICheckpoint {
}
/**
* @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 Interface that every module contract should implement
*/
interface IModule {
/**
* @notice This function returns the signature of configure function
*/
function getInitFunction() external pure returns(bytes4 initFunction);
/**
* @notice Return the permission flags that are associated with a module
*/
function getPermissions() external view returns(bytes32[] memory permissions);
}
/**
* @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 Interface that every module factory contract should implement
*/
interface IModuleFactory {
event ChangeSetupCost(uint256 _oldSetupCost, uint256 _newSetupCost);
event ChangeCostType(bool _isOldCostInPoly, bool _isNewCostInPoly);
event GenerateModuleFromFactory(
address _module,
bytes32 indexed _moduleName,
address indexed _moduleFactory,
address _creator,
uint256 _setupCost,
uint256 _setupCostInPoly
);
event ChangeSTVersionBound(string _boundType, uint8 _major, uint8 _minor, uint8 _patch);
//Should create an instance of the Module, or throw
function deploy(bytes calldata _data) external returns(address moduleAddress);
/**
* @notice Get the tags related to the module factory
*/
function version() external view returns(string memory moduleVersion);
/**
* @notice Get the tags related to the module factory
*/
function name() external view returns(bytes32 moduleName);
/**
* @notice Returns the title associated with the module
*/
function title() external view returns(string memory moduleTitle);
/**
* @notice Returns the description associated with the module
*/
function description() external view returns(string memory moduleDescription);
/**
* @notice Get the setup cost of the module in USD
*/
function setupCost() external returns(uint256 usdSetupCost);
/**
* @notice Type of the Module factory
*/
function getTypes() external view returns(uint8[] memory moduleTypes);
/**
* @notice Get the tags related to the module factory
*/
function getTags() external view returns(bytes32[] memory moduleTags);
/**
* @notice Used to change the setup fee
* @param _newSetupCost New setup fee
*/
function changeSetupCost(uint256 _newSetupCost) external;
/**
* @notice Used to change the currency and amount setup cost
* @param _setupCost new setup cost
* @param _isCostInPoly new setup cost currency. USD or POLY
*/
function changeCostAndType(uint256 _setupCost, bool _isCostInPoly) external;
/**
* @notice Function use to change the lower and upper bound of the compatible version st
* @param _boundType Type of bound
* @param _newVersion New version array
*/
function changeSTVersionBounds(string calldata _boundType, uint8[] calldata _newVersion) external;
/**
* @notice Get the setup cost of the module
*/
function setupCostInPoly() external returns (uint256 polySetupCost);
/**
* @notice Used to get the lower bound
* @return Lower bound
*/
function getLowerSTVersionBounds() external view returns(uint8[] memory lowerBounds);
/**
* @notice Used to get the upper bound
* @return Upper bound
*/
function getUpperSTVersionBounds() external view returns(uint8[] memory upperBounds);
/**
* @notice Updates the tags of the ModuleFactory
* @param _tagsData New list of tags
*/
function changeTags(bytes32[] calldata _tagsData) external;
/**
* @notice Updates the name of the ModuleFactory
* @param _name New name that will replace the old one.
*/
function changeName(bytes32 _name) external;
/**
* @notice Updates the description of the ModuleFactory
* @param _description New description that will replace the old one.
*/
function changeDescription(string calldata _description) external;
/**
* @notice Updates the title of the ModuleFactory
* @param _title New Title that will replace the old one.
*/
function changeTitle(string calldata _title) external;
}
interface IDataStore {
/**
* @dev Changes security token atatched to this data store
* @param _securityToken address of the security token
*/
function setSecurityToken(address _securityToken) external;
/**
* @dev Stores a uint256 data against a key
* @param _key Unique key to identify the data
* @param _data Data to be stored against the key
*/
function setUint256(bytes32 _key, uint256 _data) external;
function setBytes32(bytes32 _key, bytes32 _data) external;
function setAddress(bytes32 _key, address _data) external;
function setString(bytes32 _key, string calldata _data) external;
function setBytes(bytes32 _key, bytes calldata _data) external;
function setBool(bytes32 _key, bool _data) external;
/**
* @dev Stores a uint256 array against a key
* @param _key Unique key to identify the array
* @param _data Array to be stored against the key
*/
function setUint256Array(bytes32 _key, uint256[] calldata _data) external;
function setBytes32Array(bytes32 _key, bytes32[] calldata _data) external ;
function setAddressArray(bytes32 _key, address[] calldata _data) external;
function setBoolArray(bytes32 _key, bool[] calldata _data) external;
/**
* @dev Inserts a uint256 element to the array identified by the key
* @param _key Unique key to identify the array
* @param _data Element to push into the array
*/
function insertUint256(bytes32 _key, uint256 _data) external;
function insertBytes32(bytes32 _key, bytes32 _data) external;
function insertAddress(bytes32 _key, address _data) external;
function insertBool(bytes32 _key, bool _data) external;
/**
* @dev Deletes an element from the array identified by the key.
* When an element is deleted from an Array, last element of that array is moved to the index of deleted element.
* @param _key Unique key to identify the array
* @param _index Index of the element to delete
*/
function deleteUint256(bytes32 _key, uint256 _index) external;
function deleteBytes32(bytes32 _key, uint256 _index) external;
function deleteAddress(bytes32 _key, uint256 _index) external;
function deleteBool(bytes32 _key, uint256 _index) external;
/**
* @dev Stores multiple uint256 data against respective keys
* @param _keys Array of keys to identify the data
* @param _data Array of data to be stored against the respective keys
*/
function setUint256Multi(bytes32[] calldata _keys, uint256[] calldata _data) external;
function setBytes32Multi(bytes32[] calldata _keys, bytes32[] calldata _data) external;
function setAddressMulti(bytes32[] calldata _keys, address[] calldata _data) external;
function setBoolMulti(bytes32[] calldata _keys, bool[] calldata _data) external;
/**
* @dev Inserts multiple uint256 elements to the array identified by the respective keys
* @param _keys Array of keys to identify the data
* @param _data Array of data to be inserted in arrays of the respective keys
*/
function insertUint256Multi(bytes32[] calldata _keys, uint256[] calldata _data) external;
function insertBytes32Multi(bytes32[] calldata _keys, bytes32[] calldata _data) external;
function insertAddressMulti(bytes32[] calldata _keys, address[] calldata _data) external;
function insertBoolMulti(bytes32[] calldata _keys, bool[] calldata _data) external;
function getUint256(bytes32 _key) external view returns(uint256);
function getBytes32(bytes32 _key) external view returns(bytes32);
function getAddress(bytes32 _key) external view returns(address);
function getString(bytes32 _key) external view returns(string memory);
function getBytes(bytes32 _key) external view returns(bytes memory);
function getBool(bytes32 _key) external view returns(bool);
function getUint256Array(bytes32 _key) external view returns(uint256[] memory);
function getBytes32Array(bytes32 _key) external view returns(bytes32[] memory);
function getAddressArray(bytes32 _key) external view returns(address[] memory);
function getBoolArray(bytes32 _key) external view returns(bool[] memory);
function getUint256ArrayLength(bytes32 _key) external view returns(uint256);
function getBytes32ArrayLength(bytes32 _key) external view returns(uint256);
function getAddressArrayLength(bytes32 _key) external view returns(uint256);
function getBoolArrayLength(bytes32 _key) external view returns(uint256);
function getUint256ArrayElement(bytes32 _key, uint256 _index) external view returns(uint256);
function getBytes32ArrayElement(bytes32 _key, uint256 _index) external view returns(bytes32);
function getAddressArrayElement(bytes32 _key, uint256 _index) external view returns(address);
function getBoolArrayElement(bytes32 _key, uint256 _index) external view returns(bool);
function getUint256ArrayElements(bytes32 _key, uint256 _startIndex, uint256 _endIndex) external view returns(uint256[] memory);
function getBytes32ArrayElements(bytes32 _key, uint256 _startIndex, uint256 _endIndex) external view returns(bytes32[] memory);
function getAddressArrayElements(bytes32 _key, uint256 _startIndex, uint256 _endIndex) external view returns(address[] memory);
function getBoolArrayElements(bytes32 _key, uint256 _startIndex, uint256 _endIndex) external view returns(bool[] memory);
}
/**
* @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;
}
interface ICheckPermission {
/**
* @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 hasPerm);
}
/**
* @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 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 Ownable
* @dev The Ownable contract has an owner address, and provides basic authorization control
* functions, this simplifies the implementation of "user permissions".
*/
contract Ownable {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev The Ownable constructor sets the original `owner` of the contract to the sender
* account.
*/
constructor () internal {
_owner = msg.sender;
emit OwnershipTransferred(address(0), _owner);
}
/**
* @return the address of the owner.
*/
function owner() public view returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(isOwner());
_;
}
/**
* @return true if `msg.sender` is the owner of the contract.
*/
function isOwner() public view returns (bool) {
return msg.sender == _owner;
}
/**
* @dev Allows the current owner to relinquish control of the contract.
* It will not be possible to call the functions with the `onlyOwner`
* modifier anymore.
* @notice Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
/**
* @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) public onlyOwner {
_transferOwnership(newOwner);
}
/**
* @dev Transfers control of the contract to a newOwner.
* @param newOwner The address to transfer ownership to.
*/
function _transferOwnership(address newOwner) internal {
require(newOwner != address(0));
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}
/**
* @title Interface that any module contract should implement
* @notice Contract is abstract
*/
contract Module is IModule, ModuleStorage, Pausable {
/**
* @notice Constructor
* @param _securityToken Address of the security token
*/
constructor (address _securityToken, address _polyAddress) public
ModuleStorage(_securityToken, _polyAddress)
{
}
//Allows owner, factory or permissioned delegate
modifier withPerm(bytes32 _perm) {
require(_checkPerm(_perm, msg.sender), "Invalid permission");
_;
}
function _checkPerm(bytes32 _perm, address _caller) internal view returns (bool) {
bool isOwner = _caller == Ownable(address(securityToken)).owner();
bool isFactory = _caller == factory;
return isOwner || isFactory || ICheckPermission(address(securityToken)).checkPermission(_caller, address(this), _perm);
}
function _onlySecurityTokenOwner() internal view {
require(msg.sender == Ownable(address(securityToken)).owner(), "Sender is not owner");
}
modifier onlyFactory() {
require(msg.sender == factory, "Sender is not factory");
_;
}
/**
* @notice Pause (overridden function)
*/
function pause() public {
_onlySecurityTokenOwner();
super._pause();
}
/**
* @notice Unpause (overridden function)
*/
function unpause() public {
_onlySecurityTokenOwner();
super._unpause();
}
/**
* @notice used to return the data store address of securityToken
*/
function getDataStore() public view returns(IDataStore) {
return IDataStore(securityToken.dataStore());
}
/**
* @notice Reclaims ERC20Basic compatible tokens
* @dev We duplicate here due to the overriden owner & onlyOwner
* @param _tokenContract The address of the token contract
*/
function reclaimERC20(address _tokenContract) external {
_onlySecurityTokenOwner();
require(_tokenContract != address(0), "Invalid address");
IERC20 token = IERC20(_tokenContract);
uint256 balance = token.balanceOf(address(this));
require(token.transfer(msg.sender, balance), "Transfer failed");
}
/**
* @notice Reclaims ETH
* @dev We duplicate here due to the overriden owner & onlyOwner
*/
function reclaimETH() external {
_onlySecurityTokenOwner();
msg.sender.transfer(address(this).balance);
}
}
/**
* @title SafeMath
* @dev Unsigned math operations with safety checks that revert on error
*/
library SafeMath {
/**
* @dev Multiplies two unsigned integers, reverts on overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b);
return c;
}
/**
* @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
// Solidity only automatically asserts when dividing by 0
require(b > 0);
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend).
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a);
uint256 c = a - b;
return c;
}
/**
* @dev Adds two unsigned integers, reverts on overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a);
return c;
}
/**
* @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo),
* reverts when dividing by zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b != 0);
return a % b;
}
}
/**
* @title Math
* @dev Assorted math operations
*/
library Math {
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a >= b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Calculates the average of two numbers. Since these are integers,
* averages of an even and odd number cannot be represented, and will be
* rounded down.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow, so we distribute
return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);
}
}
/**
* DISCLAIMER: Under certain conditions, the function pushDividendPayment
* may fail due to block gas limits.
* If the total number of investors that ever held tokens is greater than ~15,000 then
* the function may fail. If this happens investors can pull their dividends, or the Issuer
* can use pushDividendPaymentToAddresses to provide an explict address list in batches
*/
/**
* @title Checkpoint module for issuing ether dividends
* @dev abstract contract
*/
contract DividendCheckpoint is DividendCheckpointStorage, ICheckpoint, Module {
using SafeMath for uint256;
uint256 internal constant e18 = uint256(10) ** uint256(18);
event SetDefaultExcludedAddresses(address[] _excluded);
event SetWithholding(address[] _investors, uint256[] _withholding);
event SetWithholdingFixed(address[] _investors, uint256 _withholding);
event SetWallet(address indexed _oldWallet, address indexed _newWallet);
event UpdateDividendDates(uint256 indexed _dividendIndex, uint256 _maturity, uint256 _expiry);
function _validDividendIndex(uint256 _dividendIndex) internal view {
require(_dividendIndex < dividends.length, "Invalid dividend");
require(!dividends[_dividendIndex].reclaimed, "Dividend reclaimed");
/*solium-disable-next-line security/no-block-members*/
require(now >= dividends[_dividendIndex].maturity, "Dividend maturity in future");
/*solium-disable-next-line security/no-block-members*/
require(now < dividends[_dividendIndex].expiry, "Dividend expiry in past");
}
/**
* @notice Function used to intialize the contract variables
* @param _wallet Ethereum account address to receive reclaimed dividends and tax
*/
function configure(
address payable _wallet
) public onlyFactory {
_setWallet(_wallet);
}
/**
* @notice Init function i.e generalise function to maintain the structure of the module contract
* @return bytes4
*/
function getInitFunction() public pure returns(bytes4) {
return this.configure.selector;
}
/**
* @notice Function used to change wallet address
* @param _wallet Ethereum account address to receive reclaimed dividends and tax
*/
function changeWallet(address payable _wallet) external {
_onlySecurityTokenOwner();
_setWallet(_wallet);
}
function _setWallet(address payable _wallet) internal {
emit SetWallet(wallet, _wallet);
wallet = _wallet;
}
/**
* @notice Return the default excluded addresses
* @return List of excluded addresses
*/
function getDefaultExcluded() external view returns(address[] memory) {
return excluded;
}
/**
* @notice Returns the treasury wallet address
*/
function getTreasuryWallet() public view returns(address payable) {
if (wallet == address(0)) {
address payable treasuryWallet = address(uint160(IDataStore(getDataStore()).getAddress(TREASURY)));
require(address(treasuryWallet) != address(0), "Invalid address");
return treasuryWallet;
}
else
return wallet;
}
/**
* @notice Creates a checkpoint on the security token
* @return Checkpoint ID
*/
function createCheckpoint() public withPerm(OPERATOR) returns(uint256) {
return securityToken.createCheckpoint();
}
/**
* @notice Function to clear and set list of excluded addresses used for future dividends
* @param _excluded Addresses of investors
*/
function setDefaultExcluded(address[] memory _excluded) public withPerm(ADMIN) {
require(_excluded.length <= EXCLUDED_ADDRESS_LIMIT, "Too many excluded addresses");
for (uint256 j = 0; j < _excluded.length; j++) {
require(_excluded[j] != address(0), "Invalid address");
for (uint256 i = j + 1; i < _excluded.length; i++) {
require(_excluded[j] != _excluded[i], "Duplicate exclude address");
}
}
excluded = _excluded;
/*solium-disable-next-line security/no-block-members*/
emit SetDefaultExcludedAddresses(excluded);
}
/**
* @notice Function to set withholding tax rates for investors
* @param _investors Addresses of investors
* @param _withholding Withholding tax for individual investors (multiplied by 10**16)
*/
function setWithholding(address[] memory _investors, uint256[] memory _withholding) public withPerm(ADMIN) {
require(_investors.length == _withholding.length, "Mismatched input lengths");
/*solium-disable-next-line security/no-block-members*/
emit SetWithholding(_investors, _withholding);
for (uint256 i = 0; i < _investors.length; i++) {
require(_withholding[i] <= e18, "Incorrect withholding tax");
withholdingTax[_investors[i]] = _withholding[i];
}
}
/**
* @notice Function to set withholding tax rates for investors
* @param _investors Addresses of investor
* @param _withholding Withholding tax for all investors (multiplied by 10**16)
*/
function setWithholdingFixed(address[] memory _investors, uint256 _withholding) public withPerm(ADMIN) {
require(_withholding <= e18, "Incorrect withholding tax");
/*solium-disable-next-line security/no-block-members*/
emit SetWithholdingFixed(_investors, _withholding);
for (uint256 i = 0; i < _investors.length; i++) {
withholdingTax[_investors[i]] = _withholding;
}
}
/**
* @notice Issuer can push dividends to provided addresses
* @param _dividendIndex Dividend to push
* @param _payees Addresses to which to push the dividend
*/
function pushDividendPaymentToAddresses(
uint256 _dividendIndex,
address payable[] memory _payees
)
public
withPerm(OPERATOR)
{
_validDividendIndex(_dividendIndex);
Dividend storage dividend = dividends[_dividendIndex];
for (uint256 i = 0; i < _payees.length; i++) {
if ((!dividend.claimed[_payees[i]]) && (!dividend.dividendExcluded[_payees[i]])) {
_payDividend(_payees[i], dividend, _dividendIndex);
}
}
}
/**
* @notice Issuer can push dividends using the investor list from the security token
* @param _dividendIndex Dividend to push
* @param _start Index in investor list at which to start pushing dividends
* @param _end Index in investor list at which to stop pushing dividends
*/
function pushDividendPayment(
uint256 _dividendIndex,
uint256 _start,
uint256 _end
)
public
withPerm(OPERATOR)
{
//NB If possible, please use pushDividendPaymentToAddresses as it is cheaper than this function
_validDividendIndex(_dividendIndex);
Dividend storage dividend = dividends[_dividendIndex];
uint256 checkpointId = dividend.checkpointId;
address[] memory investors = securityToken.getInvestorsSubsetAt(checkpointId, _start, _end);
// The investors list maybe smaller than _end - _start becuase it only contains addresses that had a positive balance
// the _start and _end used here are for the address list stored in the dataStore
for (uint256 i = 0; i < investors.length; i++) {
address payable payee = address(uint160(investors[i]));
if ((!dividend.claimed[payee]) && (!dividend.dividendExcluded[payee])) {
_payDividend(payee, dividend, _dividendIndex);
}
}
}
/**
* @notice Investors can pull their own dividends
* @param _dividendIndex Dividend to pull
*/
function pullDividendPayment(uint256 _dividendIndex) public whenNotPaused {
_validDividendIndex(_dividendIndex);
Dividend storage dividend = dividends[_dividendIndex];
require(!dividend.claimed[msg.sender], "Dividend already claimed");
require(!dividend.dividendExcluded[msg.sender], "msg.sender excluded from Dividend");
_payDividend(msg.sender, dividend, _dividendIndex);
}
/**
* @notice Internal function for paying dividends
* @param _payee Address of investor
* @param _dividend Storage with previously issued dividends
* @param _dividendIndex Dividend to pay
*/
function _payDividend(address payable _payee, Dividend storage _dividend, uint256 _dividendIndex) internal;
/**
* @notice Issuer can reclaim remaining unclaimed dividend amounts, for expired dividends
* @param _dividendIndex Dividend to reclaim
*/
function reclaimDividend(uint256 _dividendIndex) external;
/**
* @notice Calculate amount of dividends claimable
* @param _dividendIndex Dividend to calculate
* @param _payee Affected investor address
* @return claim, withheld amounts
*/
function calculateDividend(uint256 _dividendIndex, address _payee) public view returns(uint256, uint256) {
require(_dividendIndex < dividends.length, "Invalid dividend");
Dividend storage dividend = dividends[_dividendIndex];
if (dividend.claimed[_payee] || dividend.dividendExcluded[_payee]) {
return (0, 0);
}
uint256 balance = securityToken.balanceOfAt(_payee, dividend.checkpointId);
uint256 claim = balance.mul(dividend.amount).div(dividend.totalSupply);
uint256 withheld = claim.mul(withholdingTax[_payee]).div(e18);
return (claim, withheld);
}
/**
* @notice Get the index according to the checkpoint id
* @param _checkpointId Checkpoint id to query
* @return uint256[]
*/
function getDividendIndex(uint256 _checkpointId) public view returns(uint256[] memory) {
uint256 counter = 0;
for (uint256 i = 0; i < dividends.length; i++) {
if (dividends[i].checkpointId == _checkpointId) {
counter++;
}
}
uint256[] memory index = new uint256[](counter);
counter = 0;
for (uint256 j = 0; j < dividends.length; j++) {
if (dividends[j].checkpointId == _checkpointId) {
index[counter] = j;
counter++;
}
}
return index;
}
/**
* @notice Allows issuer to withdraw withheld tax
* @param _dividendIndex Dividend to withdraw from
*/
function withdrawWithholding(uint256 _dividendIndex) external;
/**
* @notice Allows issuer to change maturity / expiry dates for dividends
* @dev NB - setting the maturity of a currently matured dividend to a future date
* @dev will effectively refreeze claims on that dividend until the new maturity date passes
* @ dev NB - setting the expiry date to a past date will mean no more payments can be pulled
* @dev or pushed out of a dividend
* @param _dividendIndex Dividend to withdraw from
* @param _maturity updated maturity date
* @param _expiry updated expiry date
*/
function updateDividendDates(uint256 _dividendIndex, uint256 _maturity, uint256 _expiry) external withPerm(ADMIN) {
require(_dividendIndex < dividends.length, "Invalid dividend");
require(_expiry > _maturity, "Expiry before maturity");
Dividend storage dividend = dividends[_dividendIndex];
require(dividend.expiry > now, "Dividend already expired");
dividend.expiry = _expiry;
dividend.maturity = _maturity;
emit UpdateDividendDates(_dividendIndex, _maturity, _expiry);
}
/**
* @notice Get static dividend data
* @return uint256[] timestamp of dividends creation
* @return uint256[] timestamp of dividends maturity
* @return uint256[] timestamp of dividends expiry
* @return uint256[] amount of dividends
* @return uint256[] claimed amount of dividends
* @return bytes32[] name of dividends
*/
function getDividendsData() external view returns (
uint256[] memory createds,
uint256[] memory maturitys,
uint256[] memory expirys,
uint256[] memory amounts,
uint256[] memory claimedAmounts,
bytes32[] memory names)
{
createds = new uint256[](dividends.length);
maturitys = new uint256[](dividends.length);
expirys = new uint256[](dividends.length);
amounts = new uint256[](dividends.length);
claimedAmounts = new uint256[](dividends.length);
names = new bytes32[](dividends.length);
for (uint256 i = 0; i < dividends.length; i++) {
(createds[i], maturitys[i], expirys[i], amounts[i], claimedAmounts[i], names[i]) = getDividendData(i);
}
}
/**
* @notice Get static dividend data
* @return uint256 timestamp of dividend creation
* @return uint256 timestamp of dividend maturity
* @return uint256 timestamp of dividend expiry
* @return uint256 amount of dividend
* @return uint256 claimed amount of dividend
* @return bytes32 name of dividend
*/
function getDividendData(uint256 _dividendIndex) public view returns (
uint256 created,
uint256 maturity,
uint256 expiry,
uint256 amount,
uint256 claimedAmount,
bytes32 name)
{
created = dividends[_dividendIndex].created;
maturity = dividends[_dividendIndex].maturity;
expiry = dividends[_dividendIndex].expiry;
amount = dividends[_dividendIndex].amount;
claimedAmount = dividends[_dividendIndex].claimedAmount;
name = dividends[_dividendIndex].name;
}
/**
* @notice Retrieves list of investors, their claim status and whether they are excluded
* @param _dividendIndex Dividend to withdraw from
* @return address[] list of investors
* @return bool[] whether investor has claimed
* @return bool[] whether investor is excluded
* @return uint256[] amount of withheld tax (estimate if not claimed)
* @return uint256[] amount of claim (estimate if not claimeed)
* @return uint256[] investor balance
*/
function getDividendProgress(uint256 _dividendIndex) external view returns (
address[] memory investors,
bool[] memory resultClaimed,
bool[] memory resultExcluded,
uint256[] memory resultWithheld,
uint256[] memory resultAmount,
uint256[] memory resultBalance)
{
require(_dividendIndex < dividends.length, "Invalid dividend");
//Get list of Investors
Dividend storage dividend = dividends[_dividendIndex];
uint256 checkpointId = dividend.checkpointId;
investors = securityToken.getInvestorsAt(checkpointId);
resultClaimed = new bool[](investors.length);
resultExcluded = new bool[](investors.length);
resultWithheld = new uint256[](investors.length);
resultAmount = new uint256[](investors.length);
resultBalance = new uint256[](investors.length);
for (uint256 i; i < investors.length; i++) {
resultClaimed[i] = dividend.claimed[investors[i]];
resultExcluded[i] = dividend.dividendExcluded[investors[i]];
resultBalance[i] = securityToken.balanceOfAt(investors[i], dividend.checkpointId);
if (!resultExcluded[i]) {
if (resultClaimed[i]) {
resultWithheld[i] = dividend.withheld[investors[i]];
resultAmount[i] = resultBalance[i].mul(dividend.amount).div(dividend.totalSupply).sub(resultWithheld[i]);
} else {
(uint256 claim, uint256 withheld) = calculateDividend(_dividendIndex, investors[i]);
resultWithheld[i] = withheld;
resultAmount[i] = claim.sub(withheld);
}
}
}
}
/**
* @notice Retrieves list of investors, their balances, and their current withholding tax percentage
* @param _checkpointId Checkpoint Id to query for
* @return address[] list of investors
* @return uint256[] investor balances
* @return uint256[] investor withheld percentages
*/
function getCheckpointData(uint256 _checkpointId) external view returns (address[] memory investors, uint256[] memory balances, uint256[] memory withholdings) {
require(_checkpointId <= securityToken.currentCheckpointId(), "Invalid checkpoint");
investors = securityToken.getInvestorsAt(_checkpointId);
balances = new uint256[](investors.length);
withholdings = new uint256[](investors.length);
for (uint256 i; i < investors.length; i++) {
balances[i] = securityToken.balanceOfAt(investors[i], _checkpointId);
withholdings[i] = withholdingTax[investors[i]];
}
}
/**
* @notice Checks whether an address is excluded from claiming a dividend
* @param _dividendIndex Dividend to withdraw from
* @return bool whether the address is excluded
*/
function isExcluded(address _investor, uint256 _dividendIndex) external view returns (bool) {
require(_dividendIndex < dividends.length, "Invalid dividend");
return dividends[_dividendIndex].dividendExcluded[_investor];
}
/**
* @notice Checks whether an address has claimed a dividend
* @param _dividendIndex Dividend to withdraw from
* @return bool whether the address has claimed
*/
function isClaimed(address _investor, uint256 _dividendIndex) external view returns (bool) {
require(_dividendIndex < dividends.length, "Invalid dividend");
return dividends[_dividendIndex].claimed[_investor];
}
/**
* @notice Return the permissions flag that are associated with this module
* @return bytes32 array
*/
function getPermissions() public view returns(bytes32[] memory) {
bytes32[] memory allPermissions = new bytes32[](2);
allPermissions[0] = ADMIN;
allPermissions[1] = OPERATOR;
return allPermissions;
}
}
/**
* @title Ownable
* @dev The Ownable contract has an owner address, and provides basic authorization control
* functions, this simplifies the implementation of "user permissions".
*/
interface IOwnable {
/**
* @dev Returns owner
*/
function owner() external view returns(address ownerAddress);
/**
* @dev Allows the current owner to relinquish control of the contract.
*/
function renounceOwnership() external;
/**
* @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;
}
/**
* @title Checkpoint module for issuing ether dividends
*/
contract EtherDividendCheckpoint is DividendCheckpoint {
using SafeMath for uint256;
event EtherDividendDeposited(
address indexed _depositor,
uint256 _checkpointId,
uint256 _maturity,
uint256 _expiry,
uint256 _amount,
uint256 _totalSupply,
uint256 indexed _dividendIndex,
bytes32 indexed _name
);
event EtherDividendClaimed(address indexed _payee, uint256 indexed _dividendIndex, uint256 _amount, uint256 _withheld);
event EtherDividendReclaimed(address indexed _claimer, uint256 indexed _dividendIndex, uint256 _claimedAmount);
event EtherDividendClaimFailed(address indexed _payee, uint256 indexed _dividendIndex, uint256 _amount, uint256 _withheld);
event EtherDividendWithholdingWithdrawn(address indexed _claimer, uint256 indexed _dividendIndex, uint256 _withheldAmount);
/**
* @notice Constructor
* @param _securityToken Address of the security token
*/
constructor(address _securityToken, address _polyToken) public Module(_securityToken, _polyToken) {
}
/**
* @notice Creates a dividend and checkpoint for the dividend, using global list of excluded addresses
* @param _maturity Time from which dividend can be paid
* @param _expiry Time until dividend can no longer be paid, and can be reclaimed by issuer
* @param _name Name/title for identification
*/
function createDividend(uint256 _maturity, uint256 _expiry, bytes32 _name) external payable withPerm(ADMIN) {
createDividendWithExclusions(_maturity, _expiry, excluded, _name);
}
/**
* @notice Creates a dividend with a provided checkpoint, using global list of excluded addresses
* @param _maturity Time from which dividend can be paid
* @param _expiry Time until dividend can no longer be paid, and can be reclaimed by issuer
* @param _checkpointId Id of the checkpoint from which to issue dividend
* @param _name Name/title for identification
*/
function createDividendWithCheckpoint(
uint256 _maturity,
uint256 _expiry,
uint256 _checkpointId,
bytes32 _name
)
external
payable
withPerm(ADMIN)
{
_createDividendWithCheckpointAndExclusions(_maturity, _expiry, _checkpointId, excluded, _name);
}
/**
* @notice Creates a dividend and checkpoint for the dividend, specifying explicit excluded addresses
* @param _maturity Time from which dividend can be paid
* @param _expiry Time until dividend can no longer be paid, and can be reclaimed by issuer
* @param _excluded List of addresses to exclude
* @param _name Name/title for identification
*/
function createDividendWithExclusions(
uint256 _maturity,
uint256 _expiry,
address[] memory _excluded,
bytes32 _name
)
public
payable
withPerm(ADMIN)
{
uint256 checkpointId = securityToken.createCheckpoint();
_createDividendWithCheckpointAndExclusions(_maturity, _expiry, checkpointId, _excluded, _name);
}
/**
* @notice Creates a dividend with a provided checkpoint, specifying explicit excluded addresses
* @param _maturity Time from which dividend can be paid
* @param _expiry Time until dividend can no longer be paid, and can be reclaimed by issuer
* @param _checkpointId Id of the checkpoint from which to issue dividend
* @param _excluded List of addresses to exclude
* @param _name Name/title for identification
*/
function createDividendWithCheckpointAndExclusions(
uint256 _maturity,
uint256 _expiry,
uint256 _checkpointId,
address[] memory _excluded,
bytes32 _name
)
public
payable
withPerm(ADMIN)
{
_createDividendWithCheckpointAndExclusions(_maturity, _expiry, _checkpointId, _excluded, _name);
}
/**
* @notice Creates a dividend with a provided checkpoint, specifying explicit excluded addresses
* @param _maturity Time from which dividend can be paid
* @param _expiry Time until dividend can no longer be paid, and can be reclaimed by issuer
* @param _checkpointId Id of the checkpoint from which to issue dividend
* @param _excluded List of addresses to exclude
* @param _name Name/title for identification
*/
function _createDividendWithCheckpointAndExclusions(
uint256 _maturity,
uint256 _expiry,
uint256 _checkpointId,
address[] memory _excluded,
bytes32 _name
)
internal
{
require(_excluded.length <= EXCLUDED_ADDRESS_LIMIT, "Too many addresses excluded");
require(_expiry > _maturity, "Expiry is before maturity");
/*solium-disable-next-line security/no-block-members*/
require(_expiry > now, "Expiry is in the past");
require(msg.value > 0, "No dividend sent");
require(_checkpointId <= securityToken.currentCheckpointId());
require(_name[0] != bytes32(0));
uint256 dividendIndex = dividends.length;
uint256 currentSupply = securityToken.totalSupplyAt(_checkpointId);
require(currentSupply > 0, "Invalid supply");
uint256 excludedSupply = 0;
dividends.push(
Dividend(
_checkpointId,
now, /*solium-disable-line security/no-block-members*/
_maturity,
_expiry,
msg.value,
0,
0,
false,
0,
0,
_name
)
);
for (uint256 j = 0; j < _excluded.length; j++) {
require(_excluded[j] != address(0), "Invalid address");
require(!dividends[dividendIndex].dividendExcluded[_excluded[j]], "duped exclude address");
excludedSupply = excludedSupply.add(securityToken.balanceOfAt(_excluded[j], _checkpointId));
dividends[dividendIndex].dividendExcluded[_excluded[j]] = true;
}
require(currentSupply > excludedSupply, "Invalid supply");
dividends[dividendIndex].totalSupply = currentSupply - excludedSupply;
/*solium-disable-next-line security/no-block-members*/
emit EtherDividendDeposited(msg.sender, _checkpointId, _maturity, _expiry, msg.value, currentSupply, dividendIndex, _name);
}
/**
* @notice Internal function for paying dividends
* @param _payee address of investor
* @param _dividend storage with previously issued dividends
* @param _dividendIndex Dividend to pay
*/
function _payDividend(address payable _payee, Dividend storage _dividend, uint256 _dividendIndex) internal {
(uint256 claim, uint256 withheld) = calculateDividend(_dividendIndex, _payee);
_dividend.claimed[_payee] = true;
uint256 claimAfterWithheld = claim.sub(withheld);
/*solium-disable-next-line security/no-send*/
if (_payee.send(claimAfterWithheld)) {
_dividend.claimedAmount = _dividend.claimedAmount.add(claim);
if (withheld > 0) {
_dividend.totalWithheld = _dividend.totalWithheld.add(withheld);
_dividend.withheld[_payee] = withheld;
}
emit EtherDividendClaimed(_payee, _dividendIndex, claim, withheld);
} else {
_dividend.claimed[_payee] = false;
emit EtherDividendClaimFailed(_payee, _dividendIndex, claim, withheld);
}
}
/**
* @notice Issuer can reclaim remaining unclaimed dividend amounts, for expired dividends
* @param _dividendIndex Dividend to reclaim
*/
function reclaimDividend(uint256 _dividendIndex) external withPerm(OPERATOR) {
require(_dividendIndex < dividends.length, "Incorrect dividend index");
/*solium-disable-next-line security/no-block-members*/
require(now >= dividends[_dividendIndex].expiry, "Dividend expiry is in the future");
require(!dividends[_dividendIndex].reclaimed, "Dividend is already claimed");
Dividend storage dividend = dividends[_dividendIndex];
dividend.reclaimed = true;
uint256 remainingAmount = dividend.amount.sub(dividend.claimedAmount);
address payable wallet = getTreasuryWallet();
wallet.transfer(remainingAmount);
emit EtherDividendReclaimed(wallet, _dividendIndex, remainingAmount);
}
/**
* @notice Allows issuer to withdraw withheld tax
* @param _dividendIndex Dividend to withdraw from
*/
function withdrawWithholding(uint256 _dividendIndex) external withPerm(OPERATOR) {
require(_dividendIndex < dividends.length, "Incorrect dividend index");
Dividend storage dividend = dividends[_dividendIndex];
uint256 remainingWithheld = dividend.totalWithheld.sub(dividend.totalWithheldWithdrawn);
dividend.totalWithheldWithdrawn = dividend.totalWithheld;
address payable wallet = getTreasuryWallet();
wallet.transfer(remainingWithheld);
emit EtherDividendWithholdingWithdrawn(wallet, _dividendIndex, remainingWithheld);
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"constant":false,"inputs":[{"name":"_investors","type":"address[]"},{"name":"_withholding","type":"uint256"}],"name":"setWithholdingFixed","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"EXCLUDED_ADDRESS_LIMIT","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"reclaimETH","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getInitFunction","outputs":[{"name":"","type":"bytes4"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"name":"_dividendIndex","type":"uint256"}],"name":"getDividendData","outputs":[{"name":"created","type":"uint256"},{"name":"maturity","type":"uint256"},{"name":"expiry","type":"uint256"},{"name":"amount","type":"uint256"},{"name":"claimedAmount","type":"uint256"},{"name":"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":true,"inputs":[],"name":"getTreasuryWallet","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_dividendIndex","type":"uint256"}],"name":"pullDividendPayment","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_dividendIndex","type":"uint256"}],"name":"withdrawWithholding","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"investorWithheld","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"unpause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_dividendIndex","type":"uint256"},{"name":"_payees","type":"address[]"}],"name":"pushDividendPaymentToAddresses","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"wallet","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_investor","type":"address"},{"name":"_dividendIndex","type":"uint256"}],"name":"isClaimed","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_dividendIndex","type":"uint256"},{"name":"_payee","type":"address"}],"name":"calculateDividend","outputs":[{"name":"","type":"uint256"},{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_checkpointId","type":"uint256"}],"name":"getDividendIndex","outputs":[{"name":"","type":"uint256[]"}],"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":"_dividendIndex","type":"uint256"},{"name":"_maturity","type":"uint256"},{"name":"_expiry","type":"uint256"}],"name":"updateDividendDates","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_wallet","type":"address"}],"name":"configure","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"withholdingTax","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_checkpointId","type":"uint256"}],"name":"getCheckpointData","outputs":[{"name":"investors","type":"address[]"},{"name":"balances","type":"uint256[]"},{"name":"withholdings","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"dividends","outputs":[{"name":"checkpointId","type":"uint256"},{"name":"created","type":"uint256"},{"name":"maturity","type":"uint256"},{"name":"expiry","type":"uint256"},{"name":"amount","type":"uint256"},{"name":"claimedAmount","type":"uint256"},{"name":"totalSupply","type":"uint256"},{"name":"reclaimed","type":"bool"},{"name":"totalWithheld","type":"uint256"},{"name":"totalWithheldWithdrawn","type":"uint256"},{"name":"name","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_investor","type":"address"},{"name":"_dividendIndex","type":"uint256"}],"name":"isExcluded","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"pause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_investors","type":"address[]"},{"name":"_withholding","type":"uint256[]"}],"name":"setWithholding","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_tokenContract","type":"address"}],"name":"reclaimERC20","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"OPERATOR","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_wallet","type":"address"}],"name":"changeWallet","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_dividendIndex","type":"uint256"}],"name":"reclaimDividend","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getDividendsData","outputs":[{"name":"createds","type":"uint256[]"},{"name":"maturitys","type":"uint256[]"},{"name":"expirys","type":"uint256[]"},{"name":"amounts","type":"uint256[]"},{"name":"claimedAmounts","type":"uint256[]"},{"name":"names","type":"bytes32[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"securityToken","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_maturity","type":"uint256"},{"name":"_expiry","type":"uint256"},{"name":"_checkpointId","type":"uint256"},{"name":"_excluded","type":"address[]"},{"name":"_name","type":"bytes32"}],"name":"createDividendWithCheckpointAndExclusions","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"excluded","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getPermissions","outputs":[{"name":"","type":"bytes32[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"factory","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_excluded","type":"address[]"}],"name":"setDefaultExcluded","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_maturity","type":"uint256"},{"name":"_expiry","type":"uint256"},{"name":"_checkpointId","type":"uint256"},{"name":"_name","type":"bytes32"}],"name":"createDividendWithCheckpoint","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"_dividendIndex","type":"uint256"},{"name":"_start","type":"uint256"},{"name":"_end","type":"uint256"}],"name":"pushDividendPayment","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getDefaultExcluded","outputs":[{"name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_maturity","type":"uint256"},{"name":"_expiry","type":"uint256"},{"name":"_name","type":"bytes32"}],"name":"createDividend","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"_maturity","type":"uint256"},{"name":"_expiry","type":"uint256"},{"name":"_excluded","type":"address[]"},{"name":"_name","type":"bytes32"}],"name":"createDividendWithExclusions","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"name":"_dividendIndex","type":"uint256"}],"name":"getDividendProgress","outputs":[{"name":"investors","type":"address[]"},{"name":"resultClaimed","type":"bool[]"},{"name":"resultExcluded","type":"bool[]"},{"name":"resultWithheld","type":"uint256[]"},{"name":"resultAmount","type":"uint256[]"},{"name":"resultBalance","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getDataStore","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"createCheckpoint","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_securityToken","type":"address"},{"name":"_polyToken","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_depositor","type":"address"},{"indexed":false,"name":"_checkpointId","type":"uint256"},{"indexed":false,"name":"_maturity","type":"uint256"},{"indexed":false,"name":"_expiry","type":"uint256"},{"indexed":false,"name":"_amount","type":"uint256"},{"indexed":false,"name":"_totalSupply","type":"uint256"},{"indexed":true,"name":"_dividendIndex","type":"uint256"},{"indexed":true,"name":"_name","type":"bytes32"}],"name":"EtherDividendDeposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_payee","type":"address"},{"indexed":true,"name":"_dividendIndex","type":"uint256"},{"indexed":false,"name":"_amount","type":"uint256"},{"indexed":false,"name":"_withheld","type":"uint256"}],"name":"EtherDividendClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_claimer","type":"address"},{"indexed":true,"name":"_dividendIndex","type":"uint256"},{"indexed":false,"name":"_claimedAmount","type":"uint256"}],"name":"EtherDividendReclaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_payee","type":"address"},{"indexed":true,"name":"_dividendIndex","type":"uint256"},{"indexed":false,"name":"_amount","type":"uint256"},{"indexed":false,"name":"_withheld","type":"uint256"}],"name":"EtherDividendClaimFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_claimer","type":"address"},{"indexed":true,"name":"_dividendIndex","type":"uint256"},{"indexed":false,"name":"_withheldAmount","type":"uint256"}],"name":"EtherDividendWithholdingWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_excluded","type":"address[]"}],"name":"SetDefaultExcludedAddresses","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_investors","type":"address[]"},{"indexed":false,"name":"_withholding","type":"uint256[]"}],"name":"SetWithholding","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_investors","type":"address[]"},{"indexed":false,"name":"_withholding","type":"uint256"}],"name":"SetWithholdingFixed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_oldWallet","type":"address"},{"indexed":true,"name":"_newWallet","type":"address"}],"name":"SetWallet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_dividendIndex","type":"uint256"},{"indexed":false,"name":"_maturity","type":"uint256"},{"indexed":false,"name":"_expiry","type":"uint256"}],"name":"UpdateDividendDates","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"}]Contract Creation Code
6080604052609660015560088054600160a01b60ff021916905534801561002557600080fd5b5060405160408062004aaa8339810180604052604081101561004657600080fd5b508051602090910151600780546001600160a01b039384166001600160a01b0319918216179091556006805482163317905560088054939092169216919091179055614a1280620000986000396000f3fe6080604052600436106102725760003560e01c8063814b3fe01161014f578063bee2ddc2116100c1578063f1e9d1001161007a578063f1e9d10014610f20578063f4be43f414610f35578063f58b5bae14610f5e578063fa67a7bb1461100d578063fe58265e14611037578063ff0b9c901461104c57610272565b8063bee2ddc214610db9578063c3a07df614610de3578063c45a015514610df8578063cc1556dc14610e0d578063dcef4b5d14610ebb578063e1726faa14610eea57610272565b8063983d273711610113578063983d273714610aba57806398b9a2dc14610acf578063aa8b76ea14610b02578063ac121dbf14610b2c578063b84dfbd214610cee578063bea1c04114610d0357610272565b8063814b3fe01461088757806381e97b66146109095780638456cb59146109425780638596e6e6146109575780638905fd4f14610a8757610272565b80634d58e413116101e85780635daff64e116101ac5780635daff64e146106545780636faa22a5146106ce57806373e9e1a3146106e357806375cb2672146107195780637a3e23fd1461074c5780637b4a223b1461077f57610272565b80634d58e413146104d6578063521eb2731461058b578063562beba8146105a05780635bea0e1c146105ed5780635c975abb1461063f57610272565b80632a0acc6a1161023a5780632a0acc6a146103f45780632c035b741461040957806330008b481461043a578063333cffe5146104645780633f2e31651461048e5780633f4ba83a146104c157610272565b80630945812e146102775780630a29f591146103295780630f144a48146103505780631613ec9d1461036557806328d1feda14610397575b600080fd5b34801561028357600080fd5b506103276004803603604081101561029a57600080fd5b810190602081018135600160201b8111156102b457600080fd5b8201836020820111156102c657600080fd5b803590602001918460208302840111600160201b831117156102e757600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295505091359250611061915050565b005b34801561033557600080fd5b5061033e6111e5565b60408051918252519081900360200190f35b34801561035c57600080fd5b506103276111eb565b34801561037157600080fd5b5061037a611223565b604080516001600160e01b03199092168252519081900360200190f35b3480156103a357600080fd5b506103c1600480360360208110156103ba57600080fd5b5035611232565b604080519687526020870195909552858501939093526060850191909152608084015260a0830152519081900360c00190f35b34801561040057600080fd5b5061033e61130a565b34801561041557600080fd5b5061041e611319565b604080516001600160a01b039092168252519081900360200190f35b34801561044657600080fd5b506103276004803603602081101561045d57600080fd5b5035611434565b34801561047057600080fd5b506103276004803603602081101561048757600080fd5b5035611584565b34801561049a57600080fd5b5061033e600480360360208110156104b157600080fd5b50356001600160a01b031661170b565b3480156104cd57600080fd5b5061032761171d565b3480156104e257600080fd5b50610327600480360360408110156104f957600080fd5b81359190810190604081016020820135600160201b81111561051a57600080fd5b82018360208201111561052c57600080fd5b803590602001918460208302840111600160201b8311171561054d57600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092955061172f945050505050565b34801561059757600080fd5b5061041e61186b565b3480156105ac57600080fd5b506105d9600480360360408110156105c357600080fd5b506001600160a01b03813516906020013561187a565b604080519115158252519081900360200190f35b3480156105f957600080fd5b506106266004803603604081101561061057600080fd5b50803590602001356001600160a01b031661190e565b6040805192835260208301919091528051918290030190f35b34801561064b57600080fd5b506105d9611ae0565b34801561066057600080fd5b5061067e6004803603602081101561067757600080fd5b5035611af0565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156106ba5781810151838201526020016106a2565b505050509050019250505060405180910390f35b3480156106da57600080fd5b5061041e611bca565b3480156106ef57600080fd5b506103276004803603606081101561070657600080fd5b5080359060208101359060400135611bd9565b34801561072557600080fd5b506103276004803603602081101561073c57600080fd5b50356001600160a01b0316611da0565b34801561075857600080fd5b5061033e6004803603602081101561076f57600080fd5b50356001600160a01b0316611e0b565b34801561078b57600080fd5b506107a9600480360360208110156107a257600080fd5b5035611e1d565b60405180806020018060200180602001848103845287818151815260200191508051906020019060200280838360005b838110156107f15781810151838201526020016107d9565b50505050905001848103835286818151815260200191508051906020019060200280838360005b83811015610830578181015183820152602001610818565b50505050905001848103825285818151815260200191508051906020019060200280838360005b8381101561086f578181015183820152602001610857565b50505050905001965050505050505060405180910390f35b34801561089357600080fd5b506108b1600480360360208110156108aa57600080fd5b5035612156565b604080519b8c5260208c019a909a528a8a019890985260608a0196909652608089019490945260a088019290925260c0870152151560e086015261010085015261012084015261014083015251908190036101600190f35b34801561091557600080fd5b506105d96004803603604081101561092c57600080fd5b506001600160a01b0381351690602001356121c2565b34801561094e57600080fd5b50610327612255565b34801561096357600080fd5b506103276004803603604081101561097a57600080fd5b810190602081018135600160201b81111561099457600080fd5b8201836020820111156109a657600080fd5b803590602001918460208302840111600160201b831117156109c757600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b811115610a1657600080fd5b820183602082011115610a2857600080fd5b803590602001918460208302840111600160201b83111715610a4957600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550612265945050505050565b348015610a9357600080fd5b5061032760048036036020811015610aaa57600080fd5b50356001600160a01b031661249c565b348015610ac657600080fd5b5061033e61264c565b348015610adb57600080fd5b5061032760048036036020811015610af257600080fd5b50356001600160a01b031661265e565b348015610b0e57600080fd5b5061032760048036036020811015610b2557600080fd5b5035612666565b348015610b3857600080fd5b50610b416128e1565b6040518080602001806020018060200180602001806020018060200187810387528d818151815260200191508051906020019060200280838360005b83811015610b95578181015183820152602001610b7d565b5050505090500187810386528c818151815260200191508051906020019060200280838360005b83811015610bd4578181015183820152602001610bbc565b5050505090500187810385528b818151815260200191508051906020019060200280838360005b83811015610c13578181015183820152602001610bfb565b5050505090500187810384528a818151815260200191508051906020019060200280838360005b83811015610c52578181015183820152602001610c3a565b50505050905001878103835289818151815260200191508051906020019060200280838360005b83811015610c91578181015183820152602001610c79565b50505050905001878103825288818151815260200191508051906020019060200280838360005b83811015610cd0578181015183820152602001610cb8565b505050509050019c5050505050505050505050505060405180910390f35b348015610cfa57600080fd5b5061041e612ab8565b610327600480360360a0811015610d1957600080fd5b81359160208101359160408201359190810190608081016060820135600160201b811115610d4657600080fd5b820183602082011115610d5857600080fd5b803590602001918460208302840111600160201b83111715610d7957600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295505091359250612ac7915050565b348015610dc557600080fd5b5061041e60048036036020811015610ddc57600080fd5b5035612b34565b348015610def57600080fd5b5061067e612b5b565b348015610e0457600080fd5b5061041e612bd0565b348015610e1957600080fd5b5061032760048036036020811015610e3057600080fd5b810190602081018135600160201b811115610e4a57600080fd5b820183602082011115610e5c57600080fd5b803590602001918460208302840111600160201b83111715610e7d57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550612bdf945050505050565b61032760048036036080811015610ed157600080fd5b5080359060208101359060408101359060600135612e59565b348015610ef657600080fd5b5061032760048036036060811015610f0d57600080fd5b5080359060208101359060400135612f18565b348015610f2c57600080fd5b5061067e61311b565b61032760048036036060811015610f4b57600080fd5b508035906020810135906040013561317d565b61032760048036036080811015610f7457600080fd5b813591602081013591810190606081016040820135600160201b811115610f9a57600080fd5b820183602082011115610fac57600080fd5b803590602001918460208302840111600160201b83111715610fcd57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295505091359250613237915050565b34801561101957600080fd5b50610b416004803603602081101561103057600080fd5b5035613329565b34801561104357600080fd5b5061041e613871565b34801561105857600080fd5b5061033e6138ea565b600160d91b6420a226a4a70261107781336139ca565b6110b95760408051600160e51b62461bcd02815260206004820152601260248201526000805160206149a6833981519152604482015290519081900360640190fd5b670de0b6b3a76400008211156111195760408051600160e51b62461bcd02815260206004820152601960248201527f496e636f72726563742077697468686f6c64696e672074617800000000000000604482015290519081900360640190fd5b7f02d4071fbc08756ffe4bca9edb3e963c0b64703f966b7aafc724acce3e09c32b83836040518080602001838152602001828103825284818151815260200191508051906020019060200280838360005b8381101561118257818101518382015260200161116a565b50505050905001935050505060405180910390a160005b83518110156111df5782600460008684815181106111b357fe5b6020908102919091018101516001600160a01b0316825281019190915260400160002055600101611199565b50505050565b60015481565b6111f3613b00565b6040513390303180156108fc02916000818181858888f19350505050158015611220573d6000803e3d6000fd5b50565b600160e11b633ae59339025b90565b6000806000806000806002878154811061124857fe5b90600052602060002090600e02016001015495506002878154811061126957fe5b90600052602060002090600e02016002015494506002878154811061128a57fe5b90600052602060002090600e0201600301549350600287815481106112ab57fe5b90600052602060002090600e0201600401549250600287815481106112cc57fe5b90600052602060002090600e0201600501549150600287815481106112ed57fe5b90600052602060002090600e0201600d0154905091939550919395565b600160d91b6420a226a4a70281565b600080546001600160a01b0316611422576000611334613871565b6001600160a01b03166321f8a7217faae8817359f3dcb67d050f44f3e49f982e0359d90ca4b5f18569926304aaece660001b6040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561139a57600080fd5b505afa1580156113ae573d6000803e3d6000fd5b505050506040513d60208110156113c457600080fd5b505190506001600160a01b03811661141b5760408051600160e51b62461bcd02815260206004820152600f6024820152600160881b6e496e76616c6964206164647265737302604482015290519081900360640190fd5b905061122f565b506000546001600160a01b031661122f565b600854600160a01b900460ff161561148e5760408051600160e51b62461bcd0281526020600482015260126024820152600160721b7110dbdb9d1c9858dd081a5cc81c185d5cd95902604482015290519081900360640190fd5b61149781613bd9565b6000600282815481106114a657fe5b60009182526020808320338452600a600e90930201918201905260409091205490915060ff16156115215760408051600160e51b62461bcd02815260206004820152601860248201527f4469766964656e6420616c726561647920636c61696d65640000000000000000604482015290519081900360640190fd5b336000908152600b8201602052604090205460ff161561157557604051600160e51b62461bcd0281526004018080602001828103825260218152602001806149c66021913960400191505060405180910390fd5b611580338284613d8c565b5050565b600160c11b6727a822a920aa27a90261159d81336139ca565b6115df5760408051600160e51b62461bcd02815260206004820152601260248201526000805160206149a6833981519152604482015290519081900360640190fd5b60025482106116385760408051600160e51b62461bcd02815260206004820152601860248201527f496e636f7272656374206469766964656e6420696e6465780000000000000000604482015290519081900360640190fd5b60006002838154811061164757fe5b90600052602060002090600e02019050600061167482600901548360080154613f0d90919063ffffffff16565b600883015460098401559050600061168a611319565b6040519091506001600160a01b0382169083156108fc029084906000818181858888f193505050501580156116c3573d6000803e3d6000fd5b5060408051838152905186916001600160a01b038416917fc817826994cc4cf2dd66758f988195f8ad3e29078e2ce7ff40fe66477eff27e89181900360200190a35050505050565b60056020526000908152604090205481565b611725613b00565b61172d613f22565b565b600160c11b6727a822a920aa27a90261174881336139ca565b61178a5760408051600160e51b62461bcd02815260206004820152601260248201526000805160206149a6833981519152604482015290519081900360640190fd5b61179383613bd9565b6000600284815481106117a257fe5b600091825260208220600e9091020191505b83518110156118645781600a0160008583815181106117cf57fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff16158015611839575081600b01600085838151811061181057fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff16155b1561185c5761185c84828151811061184d57fe5b60200260200101518387613d8c565b6001016117b4565b5050505050565b6000546001600160a01b031681565b60025460009082106118cc5760408051600160e51b62461bcd0281526020600482015260106024820152600160821b6f125b9d985b1a5908191a5d9a59195b9902604482015290519081900360640190fd5b600282815481106118d957fe5b600091825260208083206001600160a01b0387168452600a600e90930201919091019052604090205460ff1690505b92915050565b600254600090819084106119625760408051600160e51b62461bcd0281526020600482015260106024820152600160821b6f125b9d985b1a5908191a5d9a59195b9902604482015290519081900360640190fd5b60006002858154811061197157fe5b600091825260208083206001600160a01b0388168452600a600e90930201918201905260409091205490915060ff16806119c557506001600160a01b0384166000908152600b8201602052604090205460ff165b156119d7575060009150819050611ad9565b600754815460408051600160e11b63277166bf0281526001600160a01b038881166004830152602482019390935290516000939290921691634ee2cd7e91604480820192602092909190829003018186803b158015611a3557600080fd5b505afa158015611a49573d6000803e3d6000fd5b505050506040513d6020811015611a5f57600080fd5b505160068301546004840154919250600091611a939190611a8790859063ffffffff613fc816565b9063ffffffff613ff616565b6001600160a01b03871660009081526004602052604081205491925090611acf90670de0b6b3a764000090611a8790859063ffffffff613fc816565b9195509093505050505b9250929050565b600854600160a01b900460ff1681565b60606000805b600254811015611b35578360028281548110611b0e57fe5b90600052602060002090600e0201600001541415611b2d576001909101905b600101611af6565b50606081604051908082528060200260200182016040528015611b62578160200160208202803883390190505b50600092509050815b600254811015611bc2578460028281548110611b8357fe5b90600052602060002090600e0201600001541415611bba5780828481518110611ba857fe5b60209081029190910101526001909201915b600101611b6b565b509392505050565b6008546001600160a01b031681565b600160d91b6420a226a4a702611bef81336139ca565b611c315760408051600160e51b62461bcd02815260206004820152601260248201526000805160206149a6833981519152604482015290519081900360640190fd5b6002548410611c805760408051600160e51b62461bcd0281526020600482015260106024820152600160821b6f125b9d985b1a5908191a5d9a59195b9902604482015290519081900360640190fd5b828211611cd75760408051600160e51b62461bcd02815260206004820152601660248201527f457870697279206265666f7265206d6174757269747900000000000000000000604482015290519081900360640190fd5b600060028581548110611ce657fe5b90600052602060002090600e0201905042816003015411611d515760408051600160e51b62461bcd02815260206004820152601860248201527f4469766964656e6420616c726561647920657870697265640000000000000000604482015290519081900360640190fd5b60038101839055600281018490556040805185815260208101859052815187927f4d385ba2c40259cda374f5596718ac5694e5849b23572b3f59b4fd1be037a860928290030190a25050505050565b6006546001600160a01b03163314611e025760408051600160e51b62461bcd02815260206004820152601560248201527f53656e646572206973206e6f7420666163746f72790000000000000000000000604482015290519081900360640190fd5b61122081614018565b60046020526000908152604090205481565b6060806060600760009054906101000a90046001600160a01b03166001600160a01b0316635488cc806040518163ffffffff1660e01b815260040160206040518083038186803b158015611e7057600080fd5b505afa158015611e84573d6000803e3d6000fd5b505050506040513d6020811015611e9a57600080fd5b5051841115611ef35760408051600160e51b62461bcd02815260206004820152601260248201527f496e76616c696420636865636b706f696e740000000000000000000000000000604482015290519081900360640190fd5b60075460408051600160e11b631faa9ac30281526004810187905290516001600160a01b0390921691633f55358691602480820192600092909190829003018186803b158015611f4257600080fd5b505afa158015611f56573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015611f7f57600080fd5b810190808051600160201b811115611f9657600080fd5b82016020810184811115611fa957600080fd5b81518560208202830111600160201b82111715611fc557600080fd5b505092919050505092508251604051908082528060200260200182016040528015611ffa578160200160208202803883390190505b5091508251604051908082528060200260200182016040528015612028578160200160208202803883390190505b50905060005b835181101561214e5760075484516001600160a01b0390911690634ee2cd7e9086908490811061205a57fe5b6020026020010151876040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b031681526020018281526020019250505060206040518083038186803b1580156120b057600080fd5b505afa1580156120c4573d6000803e3d6000fd5b505050506040513d60208110156120da57600080fd5b505183518490839081106120ea57fe5b6020026020010181815250506004600085838151811061210657fe5b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000205482828151811061213b57fe5b602090810291909101015260010161202e565b509193909250565b6002818154811061216357fe5b60009182526020909120600e9091020180546001820154600283015460038401546004850154600586015460068701546007880154600889015460098a0154600d909a0154989a5096989597949693959294919360ff9091169290918b565b60025460009082106122145760408051600160e51b62461bcd0281526020600482015260106024820152600160821b6f125b9d985b1a5908191a5d9a59195b9902604482015290519081900360640190fd5b6002828154811061222157fe5b600091825260208083206001600160a01b0387168452600b600e90930201919091019052604090205460ff16905092915050565b61225d613b00565b61172d614073565b600160d91b6420a226a4a70261227b81336139ca565b6122bd5760408051600160e51b62461bcd02815260206004820152601260248201526000805160206149a6833981519152604482015290519081900360640190fd5b81518351146123165760408051600160e51b62461bcd02815260206004820152601860248201527f4d69736d61746368656420696e707574206c656e677468730000000000000000604482015290519081900360640190fd5b7f01da14148cd0c4104d62830cfe6127c6955f1074631149adde6809b8687988d98383604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b8381101561237d578181015183820152602001612365565b50505050905001838103825284818151815260200191508051906020019060200280838360005b838110156123bc5781810151838201526020016123a4565b5050505090500194505050505060405180910390a160005b83518110156111df576012600a0a8382815181106123ee57fe5b6020026020010151111561244c5760408051600160e51b62461bcd02815260206004820152601960248201527f496e636f72726563742077697468686f6c64696e672074617800000000000000604482015290519081900360640190fd5b82818151811061245857fe5b60200260200101516004600086848151811061247057fe5b6020908102919091018101516001600160a01b03168252810191909152604001600020556001016123d4565b6124a4613b00565b6001600160a01b0381166124f75760408051600160e51b62461bcd02815260206004820152600f6024820152600160881b6e496e76616c6964206164647265737302604482015290519081900360640190fd5b60408051600160e01b6370a08231028152306004820152905182916000916001600160a01b038416916370a08231916024808301926020929190829003018186803b15801561254557600080fd5b505afa158015612559573d6000803e3d6000fd5b505050506040513d602081101561256f57600080fd5b505160408051600160e01b63a9059cbb0281523360048201526024810183905290519192506001600160a01b0384169163a9059cbb916044808201926020929091908290030181600087803b1580156125c757600080fd5b505af11580156125db573d6000803e3d6000fd5b505050506040513d60208110156125f157600080fd5b50516126475760408051600160e51b62461bcd02815260206004820152600f60248201527f5472616e73666572206661696c65640000000000000000000000000000000000604482015290519081900360640190fd5b505050565b600160c11b6727a822a920aa27a90281565b611e02613b00565b600160c11b6727a822a920aa27a90261267f81336139ca565b6126c15760408051600160e51b62461bcd02815260206004820152601260248201526000805160206149a6833981519152604482015290519081900360640190fd5b600254821061271a5760408051600160e51b62461bcd02815260206004820152601860248201527f496e636f7272656374206469766964656e6420696e6465780000000000000000604482015290519081900360640190fd5b6002828154811061272757fe5b90600052602060002090600e0201600301544210156127905760408051600160e51b62461bcd02815260206004820181905260248201527f4469766964656e642065787069727920697320696e2074686520667574757265604482015290519081900360640190fd5b6002828154811061279d57fe5b600091825260209091206007600e90920201015460ff16156128095760408051600160e51b62461bcd02815260206004820152601b60248201527f4469766964656e6420697320616c726561647920636c61696d65640000000000604482015290519081900360640190fd5b60006002838154811061281857fe5b6000918252602082206007600e90920201908101805460ff1916600117905560058101546004820154919350612854919063ffffffff613f0d16565b90506000612860611319565b6040519091506001600160a01b0382169083156108fc029084906000818181858888f19350505050158015612899573d6000803e3d6000fd5b5060408051838152905186916001600160a01b038416917fcd202b969101d293ad6e4c4053b46f2bf4698ca22abcb130dc24fa3baca0dee19181900360200190a35050505050565b606080606080606080600280549050604051908082528060200260200182016040528015612919578160200160208202803883390190505b506002546040805182815260208084028201019091529197508015612948578160200160208202803883390190505b506002546040805182815260208084028201019091529196508015612977578160200160208202803883390190505b5060025460408051828152602080840282010190915291955080156129a6578160200160208202803883390190505b5060025460408051828152602080840282010190915291945080156129d5578160200160208202803883390190505b506002546040805182815260208084028201019091529193508015612a04578160200160208202803883390190505b50905060005b600254811015612aaf57612a1d81611232565b8c8781518110612a2957fe5b602002602001018c8881518110612a3c57fe5b602002602001018c8981518110612a4f57fe5b602002602001018c8a81518110612a6257fe5b602002602001018c8b81518110612a7557fe5b602002602001018c8c81518110612a8857fe5b60209081029190910101959095529490935293909252929092529190915252600101612a0a565b50909192939495565b6007546001600160a01b031681565b600160d91b6420a226a4a702612add81336139ca565b612b1f5760408051600160e51b62461bcd02815260206004820152601260248201526000805160206149a6833981519152604482015290519081900360640190fd5b612b2c8686868686614118565b505050505050565b60038181548110612b4157fe5b6000918252602090912001546001600160a01b0316905081565b604080516002808252606080830184529283929190602083019080388339019050509050600160d91b6420a226a4a70281600081518110612b9857fe5b602002602001018181525050600160c11b6727a822a920aa27a90281600181518110612bc057fe5b6020908102919091010152905090565b6006546001600160a01b031681565b600160d91b6420a226a4a702612bf581336139ca565b612c375760408051600160e51b62461bcd02815260206004820152601260248201526000805160206149a6833981519152604482015290519081900360640190fd5b60015482511115612c925760408051600160e51b62461bcd02815260206004820152601b60248201527f546f6f206d616e79206578636c75646564206164647265737365730000000000604482015290519081900360640190fd5b60005b8251811015612dc05760006001600160a01b0316838281518110612cb557fe5b60200260200101516001600160a01b03161415612d115760408051600160e51b62461bcd02815260206004820152600f6024820152600160881b6e496e76616c6964206164647265737302604482015290519081900360640190fd5b600181015b8351811015612db757838181518110612d2b57fe5b60200260200101516001600160a01b0316848381518110612d4857fe5b60200260200101516001600160a01b03161415612daf5760408051600160e51b62461bcd02815260206004820152601960248201527f4475706c6963617465206578636c756465206164647265737300000000000000604482015290519081900360640190fd5b600101612d16565b50600101612c95565b508151612dd4906003906020850190614926565b507fcbdf8a4bf19b153fdd0aa4aa2c292cef47adc56e05524f1d99658f03b771e237600360405180806020018281038252838181548152602001915080548015612e4757602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612e29575b50509250505060405180910390a15050565b600160d91b6420a226a4a702612e6f81336139ca565b612eb15760408051600160e51b62461bcd02815260206004820152601260248201526000805160206149a6833981519152604482015290519081900360640190fd5b6118648585856003805480602002602001604051908101604052809291908181526020018280548015612f0d57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612eef575b505050505086614118565b600160c11b6727a822a920aa27a902612f3181336139ca565b612f735760408051600160e51b62461bcd02815260206004820152601260248201526000805160206149a6833981519152604482015290519081900360640190fd5b612f7c84613bd9565b600060028581548110612f8b57fe5b600091825260208220600e90910201805460075460408051600160e01b63abe191c102815260048101849052602481018a905260448101899052905193955091936060936001600160a01b039092169263abe191c19260648083019392829003018186803b158015612ffc57600080fd5b505afa158015613010573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561303957600080fd5b810190808051600160201b81111561305057600080fd5b8201602081018481111561306357600080fd5b81518560208202830111600160201b8211171561307f57600080fd5b50909450600093505050505b81518110156131115760008282815181106130a257fe5b6020908102919091018101516001600160a01b0381166000908152600a880190925260409091205490915060ff161580156130f857506001600160a01b0381166000908152600b8601602052604090205460ff16155b156131085761310881868b613d8c565b5060010161308b565b5050505050505050565b6060600380548060200260200160405190810160405280929190818152602001828054801561317357602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613155575b5050505050905090565b600160d91b6420a226a4a70261319381336139ca565b6131d55760408051600160e51b62461bcd02815260206004820152601260248201526000805160206149a6833981519152604482015290519081900360640190fd5b6111df8484600380548060200260200160405190810160405280929190818152602001828054801561323057602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613212575b5050505050855b600160d91b6420a226a4a70261324d81336139ca565b61328f5760408051600160e51b62461bcd02815260206004820152601260248201526000805160206149a6833981519152604482015290519081900360640190fd5b600754604080517fff0b9c9000000000000000000000000000000000000000000000000000000000815290516000926001600160a01b03169163ff0b9c9091600480830192602092919082900301818787803b1580156132ee57600080fd5b505af1158015613302573d6000803e3d6000fd5b505050506040513d602081101561331857600080fd5b50519050612b2c8686838787614118565b60608060608060608060028054905087106133845760408051600160e51b62461bcd0281526020600482015260106024820152600160821b6f125b9d985b1a5908191a5d9a59195b9902604482015290519081900360640190fd5b60006002888154811061339357fe5b600091825260208220600e90910201805460075460408051600160e11b631faa9ac302815260048101849052905193955091936001600160a01b0390911692633f553586926024808201939291829003018186803b1580156133f457600080fd5b505afa158015613408573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561343157600080fd5b810190808051600160201b81111561344857600080fd5b8201602081018481111561345b57600080fd5b81518560208202830111600160201b8211171561347757600080fd5b5050929190505050975087516040519080825280602002602001820160405280156134ac578160200160208202803883390190505b50965087516040519080825280602002602001820160405280156134da578160200160208202803883390190505b5095508751604051908082528060200260200182016040528015613508578160200160208202803883390190505b5094508751604051908082528060200260200182016040528015613536578160200160208202803883390190505b5093508751604051908082528060200260200182016040528015613564578160200160208202803883390190505b50925060005b88518110156138655782600a0160008a838151811061358557fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060009054906101000a900460ff168882815181106135c757fe5b60200260200101901515908115158152505082600b0160008a83815181106135eb57fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060009054906101000a900460ff1687828151811061362d57fe5b9115156020928302919091019091015260075489516001600160a01b0390911690634ee2cd7e908b908490811061366057fe5b602002602001015185600001546040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b031681526020018281526020019250505060206040518083038186803b1580156136ba57600080fd5b505afa1580156136ce573d6000803e3d6000fd5b505050506040513d60208110156136e457600080fd5b505184518590839081106136f457fe5b60200260200101818152505086818151811061370c57fe5b602002602001015161385d5787818151811061372457fe5b6020026020010151156137f65782600c0160008a838151811061374357fe5b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000205486828151811061377857fe5b6020026020010181815250506137d986828151811061379357fe5b60200260200101516137cd8560060154611a8787600401548987815181106137b757fe5b6020026020010151613fc890919063ffffffff16565b9063ffffffff613f0d16565b8582815181106137e557fe5b60200260200101818152505061385d565b6000806138168c8c858151811061380957fe5b602002602001015161190e565b915091508088848151811061382757fe5b6020908102919091010152613842828263ffffffff613f0d16565b87848151811061384e57fe5b60200260200101818152505050505b60010161356a565b50505091939550919395565b60075460408051600160e01b63660d0d6702815290516000926001600160a01b03169163660d0d67916004808301926020929190829003018186803b1580156138b957600080fd5b505afa1580156138cd573d6000803e3d6000fd5b505050506040513d60208110156138e357600080fd5b5051905090565b6000600160c11b6727a822a920aa27a90261390581336139ca565b6139475760408051600160e51b62461bcd02815260206004820152601260248201526000805160206149a6833981519152604482015290519081900360640190fd5b600760009054906101000a90046001600160a01b03166001600160a01b031663ff0b9c906040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561399757600080fd5b505af11580156139ab573d6000803e3d6000fd5b505050506040513d60208110156139c157600080fd5b505191505b5090565b600080600760009054906101000a90046001600160a01b03166001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b158015613a1b57600080fd5b505afa158015613a2f573d6000803e3d6000fd5b505050506040513d6020811015613a4557600080fd5b50516006546001600160a01b038581169281168314935016148180613a675750805b80613af7575060075460408051600160e01b638658b8b90281526001600160a01b0387811660048301523060248301526044820189905291519190921691638658b8b9916064808301926020929190829003018186803b158015613aca57600080fd5b505afa158015613ade573d6000803e3d6000fd5b505050506040513d6020811015613af457600080fd5b50515b95945050505050565b600760009054906101000a90046001600160a01b03166001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b158015613b4e57600080fd5b505afa158015613b62573d6000803e3d6000fd5b505050506040513d6020811015613b7857600080fd5b50516001600160a01b0316331461172d5760408051600160e51b62461bcd02815260206004820152601360248201527f53656e646572206973206e6f74206f776e657200000000000000000000000000604482015290519081900360640190fd5b6002548110613c285760408051600160e51b62461bcd0281526020600482015260106024820152600160821b6f125b9d985b1a5908191a5d9a59195b9902604482015290519081900360640190fd5b60028181548110613c3557fe5b600091825260209091206007600e90920201015460ff1615613ca15760408051600160e51b62461bcd02815260206004820152601260248201527f4469766964656e64207265636c61696d65640000000000000000000000000000604482015290519081900360640190fd5b60028181548110613cae57fe5b90600052602060002090600e020160020154421015613d175760408051600160e51b62461bcd02815260206004820152601b60248201527f4469766964656e64206d6174757269747920696e206675747572650000000000604482015290519081900360640190fd5b60028181548110613d2457fe5b90600052602060002090600e02016003015442106112205760408051600160e51b62461bcd02815260206004820152601760248201527f4469766964656e642065787069727920696e2070617374000000000000000000604482015290519081900360640190fd5b600080613d99838661190e565b6001600160a01b0387166000908152600a870160205260408120805460ff191660011790559193509150613dd3838363ffffffff613f0d16565b6040519091506001600160a01b0387169082156108fc029083906000818181858888f1935050505015613ea7576005850154613e15908463ffffffff61491416565b60058601558115613e58576008850154613e35908363ffffffff61491416565b60088601556001600160a01b0386166000908152600c8601602052604090208290555b83866001600160a01b03167f0cfb57b295d2603fbb329fdc2d35326148368bf26a74cbb525cdf3a71ff5cc3d8585604051808381526020018281526020019250505060405180910390a3612b2c565b6001600160a01b0386166000818152600a87016020908152604091829020805460ff19169055815186815290810185905281518793927fd252e7e7f5d6262d6dd8f80698d23f219cd7847a22b97c199a5984440f3c2715928290030190a3505050505050565b600082821115613f1c57600080fd5b50900390565b600854600160a01b900460ff16613f835760408051600160e51b62461bcd02815260206004820152601660248201527f436f6e7472616374206973206e6f742070617573656400000000000000000000604482015290519081900360640190fd5b60088054600160a01b60ff02191690556040805133815290517faeb196d352664784d1900b0e7414a8face7d29f4dae8c4b0cf68ed477423bbf49181900360200190a1565b600082613fd757506000611908565b82820282848281613fe457fe5b0414613fef57600080fd5b9392505050565b600080821161400457600080fd5b600082848161400f57fe5b04949350505050565b600080546040516001600160a01b03808516939216917f8595877311e370fe3ac87d4f6d12473603393f02ac660e68d2e5e3da5adb610c91a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b600854600160a01b900460ff16156140cd5760408051600160e51b62461bcd0281526020600482015260126024820152600160721b7110dbdb9d1c9858dd081a5cc81c185d5cd95902604482015290519081900360640190fd5b60088054600160a01b60ff021916600160a01b1790556040805133815290517f5ee71a369c8672edded508e624ffc9257fa1ae6886ef32905c18e60196bca3999181900360200190a1565b600154825111156141735760408051600160e51b62461bcd02815260206004820152601b60248201527f546f6f206d616e7920616464726573736573206578636c756465640000000000604482015290519081900360640190fd5b8484116141ca5760408051600160e51b62461bcd02815260206004820152601960248201527f457870697279206973206265666f7265206d6174757269747900000000000000604482015290519081900360640190fd5b4284116142215760408051600160e51b62461bcd02815260206004820152601560248201527f45787069727920697320696e2074686520706173740000000000000000000000604482015290519081900360640190fd5b600034116142795760408051600160e51b62461bcd02815260206004820152601060248201527f4e6f206469766964656e642073656e7400000000000000000000000000000000604482015290519081900360640190fd5b600760009054906101000a90046001600160a01b03166001600160a01b0316635488cc806040518163ffffffff1660e01b815260040160206040518083038186803b1580156142c757600080fd5b505afa1580156142db573d6000803e3d6000fd5b505050506040513d60208110156142f157600080fd5b50518311156142ff57600080fd5b6001600160f81b0319600082901a60f81b1661431a57600080fd5b60025460075460408051600160e41b630981b24d0281526004810187905290516000926001600160a01b03169163981b24d0916024808301926020929190829003018186803b15801561436c57600080fd5b505afa158015614380573d6000803e3d6000fd5b505050506040513d602081101561439657600080fd5b50519050806143e35760408051600160e51b62461bcd02815260206004820152600e6024820152600160901b6d496e76616c696420737570706c7902604482015290519081900360640190fd5b60408051610160810182528681524260208201908152918101898152606082018981523460808401908152600060a0850181815260c0860182815260e08701838152610100880184815261012089018581526101408a018e8152600280546001810182559088529a517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace600e909c029b8c01559a517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf8b015597517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad08a015595517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad189015593517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad288015590517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad3870155517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad486015590517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad58501805460ff191691151591909117905590517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad684015590517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad783015591517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5adb90910155805b85518110156148445760006001600160a01b031686828151811061462257fe5b60200260200101516001600160a01b0316141561467e5760408051600160e51b62461bcd02815260206004820152600f6024820152600160881b6e496e76616c6964206164647265737302604482015290519081900360640190fd5b6002848154811061468b57fe5b90600052602060002090600e0201600b0160008783815181106146aa57fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff16156147265760408051600160e51b62461bcd02815260206004820152601560248201527f6475706564206578636c75646520616464726573730000000000000000000000604482015290519081900360640190fd5b60075486516147da916001600160a01b031690634ee2cd7e9089908590811061474b57fe5b60200260200101518a6040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b031681526020018281526020019250505060206040518083038186803b1580156147a157600080fd5b505afa1580156147b5573d6000803e3d6000fd5b505050506040513d60208110156147cb57600080fd5b5051839063ffffffff61491416565b91506001600285815481106147eb57fe5b90600052602060002090600e0201600b01600088848151811061480a57fe5b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff1916911515919091179055600101614602565b508082116148905760408051600160e51b62461bcd02815260206004820152600e6024820152600160901b6d496e76616c696420737570706c7902604482015290519081900360640190fd5b808203600284815481106148a057fe5b60009182526020918290206006600e909202010191909155604080518881529182018a905281810189905234606083015260808201849052518591859133917f376302a393407da8edbd629bc870b9ae0cca86e0b83dbe5b349854743ab55a53919081900360a00190a45050505050505050565b600082820183811015613fef57600080fd5b82805482825590600052602060002090810192821561497b579160200282015b8281111561497b57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614946565b506139c69261122f9250905b808211156139c65780546001600160a01b031916815560010161498756fe496e76616c6964207065726d697373696f6e00000000000000000000000000006d73672e73656e646572206578636c756465642066726f6d204469766964656e64a165627a7a72305820224c07420b1a9606109af0b36437eeb86393f9c1ca92b04932022fca62a7dbe8002900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436106102725760003560e01c8063814b3fe01161014f578063bee2ddc2116100c1578063f1e9d1001161007a578063f1e9d10014610f20578063f4be43f414610f35578063f58b5bae14610f5e578063fa67a7bb1461100d578063fe58265e14611037578063ff0b9c901461104c57610272565b8063bee2ddc214610db9578063c3a07df614610de3578063c45a015514610df8578063cc1556dc14610e0d578063dcef4b5d14610ebb578063e1726faa14610eea57610272565b8063983d273711610113578063983d273714610aba57806398b9a2dc14610acf578063aa8b76ea14610b02578063ac121dbf14610b2c578063b84dfbd214610cee578063bea1c04114610d0357610272565b8063814b3fe01461088757806381e97b66146109095780638456cb59146109425780638596e6e6146109575780638905fd4f14610a8757610272565b80634d58e413116101e85780635daff64e116101ac5780635daff64e146106545780636faa22a5146106ce57806373e9e1a3146106e357806375cb2672146107195780637a3e23fd1461074c5780637b4a223b1461077f57610272565b80634d58e413146104d6578063521eb2731461058b578063562beba8146105a05780635bea0e1c146105ed5780635c975abb1461063f57610272565b80632a0acc6a1161023a5780632a0acc6a146103f45780632c035b741461040957806330008b481461043a578063333cffe5146104645780633f2e31651461048e5780633f4ba83a146104c157610272565b80630945812e146102775780630a29f591146103295780630f144a48146103505780631613ec9d1461036557806328d1feda14610397575b600080fd5b34801561028357600080fd5b506103276004803603604081101561029a57600080fd5b810190602081018135600160201b8111156102b457600080fd5b8201836020820111156102c657600080fd5b803590602001918460208302840111600160201b831117156102e757600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295505091359250611061915050565b005b34801561033557600080fd5b5061033e6111e5565b60408051918252519081900360200190f35b34801561035c57600080fd5b506103276111eb565b34801561037157600080fd5b5061037a611223565b604080516001600160e01b03199092168252519081900360200190f35b3480156103a357600080fd5b506103c1600480360360208110156103ba57600080fd5b5035611232565b604080519687526020870195909552858501939093526060850191909152608084015260a0830152519081900360c00190f35b34801561040057600080fd5b5061033e61130a565b34801561041557600080fd5b5061041e611319565b604080516001600160a01b039092168252519081900360200190f35b34801561044657600080fd5b506103276004803603602081101561045d57600080fd5b5035611434565b34801561047057600080fd5b506103276004803603602081101561048757600080fd5b5035611584565b34801561049a57600080fd5b5061033e600480360360208110156104b157600080fd5b50356001600160a01b031661170b565b3480156104cd57600080fd5b5061032761171d565b3480156104e257600080fd5b50610327600480360360408110156104f957600080fd5b81359190810190604081016020820135600160201b81111561051a57600080fd5b82018360208201111561052c57600080fd5b803590602001918460208302840111600160201b8311171561054d57600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092955061172f945050505050565b34801561059757600080fd5b5061041e61186b565b3480156105ac57600080fd5b506105d9600480360360408110156105c357600080fd5b506001600160a01b03813516906020013561187a565b604080519115158252519081900360200190f35b3480156105f957600080fd5b506106266004803603604081101561061057600080fd5b50803590602001356001600160a01b031661190e565b6040805192835260208301919091528051918290030190f35b34801561064b57600080fd5b506105d9611ae0565b34801561066057600080fd5b5061067e6004803603602081101561067757600080fd5b5035611af0565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156106ba5781810151838201526020016106a2565b505050509050019250505060405180910390f35b3480156106da57600080fd5b5061041e611bca565b3480156106ef57600080fd5b506103276004803603606081101561070657600080fd5b5080359060208101359060400135611bd9565b34801561072557600080fd5b506103276004803603602081101561073c57600080fd5b50356001600160a01b0316611da0565b34801561075857600080fd5b5061033e6004803603602081101561076f57600080fd5b50356001600160a01b0316611e0b565b34801561078b57600080fd5b506107a9600480360360208110156107a257600080fd5b5035611e1d565b60405180806020018060200180602001848103845287818151815260200191508051906020019060200280838360005b838110156107f15781810151838201526020016107d9565b50505050905001848103835286818151815260200191508051906020019060200280838360005b83811015610830578181015183820152602001610818565b50505050905001848103825285818151815260200191508051906020019060200280838360005b8381101561086f578181015183820152602001610857565b50505050905001965050505050505060405180910390f35b34801561089357600080fd5b506108b1600480360360208110156108aa57600080fd5b5035612156565b604080519b8c5260208c019a909a528a8a019890985260608a0196909652608089019490945260a088019290925260c0870152151560e086015261010085015261012084015261014083015251908190036101600190f35b34801561091557600080fd5b506105d96004803603604081101561092c57600080fd5b506001600160a01b0381351690602001356121c2565b34801561094e57600080fd5b50610327612255565b34801561096357600080fd5b506103276004803603604081101561097a57600080fd5b810190602081018135600160201b81111561099457600080fd5b8201836020820111156109a657600080fd5b803590602001918460208302840111600160201b831117156109c757600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b811115610a1657600080fd5b820183602082011115610a2857600080fd5b803590602001918460208302840111600160201b83111715610a4957600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550612265945050505050565b348015610a9357600080fd5b5061032760048036036020811015610aaa57600080fd5b50356001600160a01b031661249c565b348015610ac657600080fd5b5061033e61264c565b348015610adb57600080fd5b5061032760048036036020811015610af257600080fd5b50356001600160a01b031661265e565b348015610b0e57600080fd5b5061032760048036036020811015610b2557600080fd5b5035612666565b348015610b3857600080fd5b50610b416128e1565b6040518080602001806020018060200180602001806020018060200187810387528d818151815260200191508051906020019060200280838360005b83811015610b95578181015183820152602001610b7d565b5050505090500187810386528c818151815260200191508051906020019060200280838360005b83811015610bd4578181015183820152602001610bbc565b5050505090500187810385528b818151815260200191508051906020019060200280838360005b83811015610c13578181015183820152602001610bfb565b5050505090500187810384528a818151815260200191508051906020019060200280838360005b83811015610c52578181015183820152602001610c3a565b50505050905001878103835289818151815260200191508051906020019060200280838360005b83811015610c91578181015183820152602001610c79565b50505050905001878103825288818151815260200191508051906020019060200280838360005b83811015610cd0578181015183820152602001610cb8565b505050509050019c5050505050505050505050505060405180910390f35b348015610cfa57600080fd5b5061041e612ab8565b610327600480360360a0811015610d1957600080fd5b81359160208101359160408201359190810190608081016060820135600160201b811115610d4657600080fd5b820183602082011115610d5857600080fd5b803590602001918460208302840111600160201b83111715610d7957600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295505091359250612ac7915050565b348015610dc557600080fd5b5061041e60048036036020811015610ddc57600080fd5b5035612b34565b348015610def57600080fd5b5061067e612b5b565b348015610e0457600080fd5b5061041e612bd0565b348015610e1957600080fd5b5061032760048036036020811015610e3057600080fd5b810190602081018135600160201b811115610e4a57600080fd5b820183602082011115610e5c57600080fd5b803590602001918460208302840111600160201b83111715610e7d57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550612bdf945050505050565b61032760048036036080811015610ed157600080fd5b5080359060208101359060408101359060600135612e59565b348015610ef657600080fd5b5061032760048036036060811015610f0d57600080fd5b5080359060208101359060400135612f18565b348015610f2c57600080fd5b5061067e61311b565b61032760048036036060811015610f4b57600080fd5b508035906020810135906040013561317d565b61032760048036036080811015610f7457600080fd5b813591602081013591810190606081016040820135600160201b811115610f9a57600080fd5b820183602082011115610fac57600080fd5b803590602001918460208302840111600160201b83111715610fcd57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295505091359250613237915050565b34801561101957600080fd5b50610b416004803603602081101561103057600080fd5b5035613329565b34801561104357600080fd5b5061041e613871565b34801561105857600080fd5b5061033e6138ea565b600160d91b6420a226a4a70261107781336139ca565b6110b95760408051600160e51b62461bcd02815260206004820152601260248201526000805160206149a6833981519152604482015290519081900360640190fd5b670de0b6b3a76400008211156111195760408051600160e51b62461bcd02815260206004820152601960248201527f496e636f72726563742077697468686f6c64696e672074617800000000000000604482015290519081900360640190fd5b7f02d4071fbc08756ffe4bca9edb3e963c0b64703f966b7aafc724acce3e09c32b83836040518080602001838152602001828103825284818151815260200191508051906020019060200280838360005b8381101561118257818101518382015260200161116a565b50505050905001935050505060405180910390a160005b83518110156111df5782600460008684815181106111b357fe5b6020908102919091018101516001600160a01b0316825281019190915260400160002055600101611199565b50505050565b60015481565b6111f3613b00565b6040513390303180156108fc02916000818181858888f19350505050158015611220573d6000803e3d6000fd5b50565b600160e11b633ae59339025b90565b6000806000806000806002878154811061124857fe5b90600052602060002090600e02016001015495506002878154811061126957fe5b90600052602060002090600e02016002015494506002878154811061128a57fe5b90600052602060002090600e0201600301549350600287815481106112ab57fe5b90600052602060002090600e0201600401549250600287815481106112cc57fe5b90600052602060002090600e0201600501549150600287815481106112ed57fe5b90600052602060002090600e0201600d0154905091939550919395565b600160d91b6420a226a4a70281565b600080546001600160a01b0316611422576000611334613871565b6001600160a01b03166321f8a7217faae8817359f3dcb67d050f44f3e49f982e0359d90ca4b5f18569926304aaece660001b6040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561139a57600080fd5b505afa1580156113ae573d6000803e3d6000fd5b505050506040513d60208110156113c457600080fd5b505190506001600160a01b03811661141b5760408051600160e51b62461bcd02815260206004820152600f6024820152600160881b6e496e76616c6964206164647265737302604482015290519081900360640190fd5b905061122f565b506000546001600160a01b031661122f565b600854600160a01b900460ff161561148e5760408051600160e51b62461bcd0281526020600482015260126024820152600160721b7110dbdb9d1c9858dd081a5cc81c185d5cd95902604482015290519081900360640190fd5b61149781613bd9565b6000600282815481106114a657fe5b60009182526020808320338452600a600e90930201918201905260409091205490915060ff16156115215760408051600160e51b62461bcd02815260206004820152601860248201527f4469766964656e6420616c726561647920636c61696d65640000000000000000604482015290519081900360640190fd5b336000908152600b8201602052604090205460ff161561157557604051600160e51b62461bcd0281526004018080602001828103825260218152602001806149c66021913960400191505060405180910390fd5b611580338284613d8c565b5050565b600160c11b6727a822a920aa27a90261159d81336139ca565b6115df5760408051600160e51b62461bcd02815260206004820152601260248201526000805160206149a6833981519152604482015290519081900360640190fd5b60025482106116385760408051600160e51b62461bcd02815260206004820152601860248201527f496e636f7272656374206469766964656e6420696e6465780000000000000000604482015290519081900360640190fd5b60006002838154811061164757fe5b90600052602060002090600e02019050600061167482600901548360080154613f0d90919063ffffffff16565b600883015460098401559050600061168a611319565b6040519091506001600160a01b0382169083156108fc029084906000818181858888f193505050501580156116c3573d6000803e3d6000fd5b5060408051838152905186916001600160a01b038416917fc817826994cc4cf2dd66758f988195f8ad3e29078e2ce7ff40fe66477eff27e89181900360200190a35050505050565b60056020526000908152604090205481565b611725613b00565b61172d613f22565b565b600160c11b6727a822a920aa27a90261174881336139ca565b61178a5760408051600160e51b62461bcd02815260206004820152601260248201526000805160206149a6833981519152604482015290519081900360640190fd5b61179383613bd9565b6000600284815481106117a257fe5b600091825260208220600e9091020191505b83518110156118645781600a0160008583815181106117cf57fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff16158015611839575081600b01600085838151811061181057fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff16155b1561185c5761185c84828151811061184d57fe5b60200260200101518387613d8c565b6001016117b4565b5050505050565b6000546001600160a01b031681565b60025460009082106118cc5760408051600160e51b62461bcd0281526020600482015260106024820152600160821b6f125b9d985b1a5908191a5d9a59195b9902604482015290519081900360640190fd5b600282815481106118d957fe5b600091825260208083206001600160a01b0387168452600a600e90930201919091019052604090205460ff1690505b92915050565b600254600090819084106119625760408051600160e51b62461bcd0281526020600482015260106024820152600160821b6f125b9d985b1a5908191a5d9a59195b9902604482015290519081900360640190fd5b60006002858154811061197157fe5b600091825260208083206001600160a01b0388168452600a600e90930201918201905260409091205490915060ff16806119c557506001600160a01b0384166000908152600b8201602052604090205460ff165b156119d7575060009150819050611ad9565b600754815460408051600160e11b63277166bf0281526001600160a01b038881166004830152602482019390935290516000939290921691634ee2cd7e91604480820192602092909190829003018186803b158015611a3557600080fd5b505afa158015611a49573d6000803e3d6000fd5b505050506040513d6020811015611a5f57600080fd5b505160068301546004840154919250600091611a939190611a8790859063ffffffff613fc816565b9063ffffffff613ff616565b6001600160a01b03871660009081526004602052604081205491925090611acf90670de0b6b3a764000090611a8790859063ffffffff613fc816565b9195509093505050505b9250929050565b600854600160a01b900460ff1681565b60606000805b600254811015611b35578360028281548110611b0e57fe5b90600052602060002090600e0201600001541415611b2d576001909101905b600101611af6565b50606081604051908082528060200260200182016040528015611b62578160200160208202803883390190505b50600092509050815b600254811015611bc2578460028281548110611b8357fe5b90600052602060002090600e0201600001541415611bba5780828481518110611ba857fe5b60209081029190910101526001909201915b600101611b6b565b509392505050565b6008546001600160a01b031681565b600160d91b6420a226a4a702611bef81336139ca565b611c315760408051600160e51b62461bcd02815260206004820152601260248201526000805160206149a6833981519152604482015290519081900360640190fd5b6002548410611c805760408051600160e51b62461bcd0281526020600482015260106024820152600160821b6f125b9d985b1a5908191a5d9a59195b9902604482015290519081900360640190fd5b828211611cd75760408051600160e51b62461bcd02815260206004820152601660248201527f457870697279206265666f7265206d6174757269747900000000000000000000604482015290519081900360640190fd5b600060028581548110611ce657fe5b90600052602060002090600e0201905042816003015411611d515760408051600160e51b62461bcd02815260206004820152601860248201527f4469766964656e6420616c726561647920657870697265640000000000000000604482015290519081900360640190fd5b60038101839055600281018490556040805185815260208101859052815187927f4d385ba2c40259cda374f5596718ac5694e5849b23572b3f59b4fd1be037a860928290030190a25050505050565b6006546001600160a01b03163314611e025760408051600160e51b62461bcd02815260206004820152601560248201527f53656e646572206973206e6f7420666163746f72790000000000000000000000604482015290519081900360640190fd5b61122081614018565b60046020526000908152604090205481565b6060806060600760009054906101000a90046001600160a01b03166001600160a01b0316635488cc806040518163ffffffff1660e01b815260040160206040518083038186803b158015611e7057600080fd5b505afa158015611e84573d6000803e3d6000fd5b505050506040513d6020811015611e9a57600080fd5b5051841115611ef35760408051600160e51b62461bcd02815260206004820152601260248201527f496e76616c696420636865636b706f696e740000000000000000000000000000604482015290519081900360640190fd5b60075460408051600160e11b631faa9ac30281526004810187905290516001600160a01b0390921691633f55358691602480820192600092909190829003018186803b158015611f4257600080fd5b505afa158015611f56573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015611f7f57600080fd5b810190808051600160201b811115611f9657600080fd5b82016020810184811115611fa957600080fd5b81518560208202830111600160201b82111715611fc557600080fd5b505092919050505092508251604051908082528060200260200182016040528015611ffa578160200160208202803883390190505b5091508251604051908082528060200260200182016040528015612028578160200160208202803883390190505b50905060005b835181101561214e5760075484516001600160a01b0390911690634ee2cd7e9086908490811061205a57fe5b6020026020010151876040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b031681526020018281526020019250505060206040518083038186803b1580156120b057600080fd5b505afa1580156120c4573d6000803e3d6000fd5b505050506040513d60208110156120da57600080fd5b505183518490839081106120ea57fe5b6020026020010181815250506004600085838151811061210657fe5b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000205482828151811061213b57fe5b602090810291909101015260010161202e565b509193909250565b6002818154811061216357fe5b60009182526020909120600e9091020180546001820154600283015460038401546004850154600586015460068701546007880154600889015460098a0154600d909a0154989a5096989597949693959294919360ff9091169290918b565b60025460009082106122145760408051600160e51b62461bcd0281526020600482015260106024820152600160821b6f125b9d985b1a5908191a5d9a59195b9902604482015290519081900360640190fd5b6002828154811061222157fe5b600091825260208083206001600160a01b0387168452600b600e90930201919091019052604090205460ff16905092915050565b61225d613b00565b61172d614073565b600160d91b6420a226a4a70261227b81336139ca565b6122bd5760408051600160e51b62461bcd02815260206004820152601260248201526000805160206149a6833981519152604482015290519081900360640190fd5b81518351146123165760408051600160e51b62461bcd02815260206004820152601860248201527f4d69736d61746368656420696e707574206c656e677468730000000000000000604482015290519081900360640190fd5b7f01da14148cd0c4104d62830cfe6127c6955f1074631149adde6809b8687988d98383604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b8381101561237d578181015183820152602001612365565b50505050905001838103825284818151815260200191508051906020019060200280838360005b838110156123bc5781810151838201526020016123a4565b5050505090500194505050505060405180910390a160005b83518110156111df576012600a0a8382815181106123ee57fe5b6020026020010151111561244c5760408051600160e51b62461bcd02815260206004820152601960248201527f496e636f72726563742077697468686f6c64696e672074617800000000000000604482015290519081900360640190fd5b82818151811061245857fe5b60200260200101516004600086848151811061247057fe5b6020908102919091018101516001600160a01b03168252810191909152604001600020556001016123d4565b6124a4613b00565b6001600160a01b0381166124f75760408051600160e51b62461bcd02815260206004820152600f6024820152600160881b6e496e76616c6964206164647265737302604482015290519081900360640190fd5b60408051600160e01b6370a08231028152306004820152905182916000916001600160a01b038416916370a08231916024808301926020929190829003018186803b15801561254557600080fd5b505afa158015612559573d6000803e3d6000fd5b505050506040513d602081101561256f57600080fd5b505160408051600160e01b63a9059cbb0281523360048201526024810183905290519192506001600160a01b0384169163a9059cbb916044808201926020929091908290030181600087803b1580156125c757600080fd5b505af11580156125db573d6000803e3d6000fd5b505050506040513d60208110156125f157600080fd5b50516126475760408051600160e51b62461bcd02815260206004820152600f60248201527f5472616e73666572206661696c65640000000000000000000000000000000000604482015290519081900360640190fd5b505050565b600160c11b6727a822a920aa27a90281565b611e02613b00565b600160c11b6727a822a920aa27a90261267f81336139ca565b6126c15760408051600160e51b62461bcd02815260206004820152601260248201526000805160206149a6833981519152604482015290519081900360640190fd5b600254821061271a5760408051600160e51b62461bcd02815260206004820152601860248201527f496e636f7272656374206469766964656e6420696e6465780000000000000000604482015290519081900360640190fd5b6002828154811061272757fe5b90600052602060002090600e0201600301544210156127905760408051600160e51b62461bcd02815260206004820181905260248201527f4469766964656e642065787069727920697320696e2074686520667574757265604482015290519081900360640190fd5b6002828154811061279d57fe5b600091825260209091206007600e90920201015460ff16156128095760408051600160e51b62461bcd02815260206004820152601b60248201527f4469766964656e6420697320616c726561647920636c61696d65640000000000604482015290519081900360640190fd5b60006002838154811061281857fe5b6000918252602082206007600e90920201908101805460ff1916600117905560058101546004820154919350612854919063ffffffff613f0d16565b90506000612860611319565b6040519091506001600160a01b0382169083156108fc029084906000818181858888f19350505050158015612899573d6000803e3d6000fd5b5060408051838152905186916001600160a01b038416917fcd202b969101d293ad6e4c4053b46f2bf4698ca22abcb130dc24fa3baca0dee19181900360200190a35050505050565b606080606080606080600280549050604051908082528060200260200182016040528015612919578160200160208202803883390190505b506002546040805182815260208084028201019091529197508015612948578160200160208202803883390190505b506002546040805182815260208084028201019091529196508015612977578160200160208202803883390190505b5060025460408051828152602080840282010190915291955080156129a6578160200160208202803883390190505b5060025460408051828152602080840282010190915291945080156129d5578160200160208202803883390190505b506002546040805182815260208084028201019091529193508015612a04578160200160208202803883390190505b50905060005b600254811015612aaf57612a1d81611232565b8c8781518110612a2957fe5b602002602001018c8881518110612a3c57fe5b602002602001018c8981518110612a4f57fe5b602002602001018c8a81518110612a6257fe5b602002602001018c8b81518110612a7557fe5b602002602001018c8c81518110612a8857fe5b60209081029190910101959095529490935293909252929092529190915252600101612a0a565b50909192939495565b6007546001600160a01b031681565b600160d91b6420a226a4a702612add81336139ca565b612b1f5760408051600160e51b62461bcd02815260206004820152601260248201526000805160206149a6833981519152604482015290519081900360640190fd5b612b2c8686868686614118565b505050505050565b60038181548110612b4157fe5b6000918252602090912001546001600160a01b0316905081565b604080516002808252606080830184529283929190602083019080388339019050509050600160d91b6420a226a4a70281600081518110612b9857fe5b602002602001018181525050600160c11b6727a822a920aa27a90281600181518110612bc057fe5b6020908102919091010152905090565b6006546001600160a01b031681565b600160d91b6420a226a4a702612bf581336139ca565b612c375760408051600160e51b62461bcd02815260206004820152601260248201526000805160206149a6833981519152604482015290519081900360640190fd5b60015482511115612c925760408051600160e51b62461bcd02815260206004820152601b60248201527f546f6f206d616e79206578636c75646564206164647265737365730000000000604482015290519081900360640190fd5b60005b8251811015612dc05760006001600160a01b0316838281518110612cb557fe5b60200260200101516001600160a01b03161415612d115760408051600160e51b62461bcd02815260206004820152600f6024820152600160881b6e496e76616c6964206164647265737302604482015290519081900360640190fd5b600181015b8351811015612db757838181518110612d2b57fe5b60200260200101516001600160a01b0316848381518110612d4857fe5b60200260200101516001600160a01b03161415612daf5760408051600160e51b62461bcd02815260206004820152601960248201527f4475706c6963617465206578636c756465206164647265737300000000000000604482015290519081900360640190fd5b600101612d16565b50600101612c95565b508151612dd4906003906020850190614926565b507fcbdf8a4bf19b153fdd0aa4aa2c292cef47adc56e05524f1d99658f03b771e237600360405180806020018281038252838181548152602001915080548015612e4757602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612e29575b50509250505060405180910390a15050565b600160d91b6420a226a4a702612e6f81336139ca565b612eb15760408051600160e51b62461bcd02815260206004820152601260248201526000805160206149a6833981519152604482015290519081900360640190fd5b6118648585856003805480602002602001604051908101604052809291908181526020018280548015612f0d57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612eef575b505050505086614118565b600160c11b6727a822a920aa27a902612f3181336139ca565b612f735760408051600160e51b62461bcd02815260206004820152601260248201526000805160206149a6833981519152604482015290519081900360640190fd5b612f7c84613bd9565b600060028581548110612f8b57fe5b600091825260208220600e90910201805460075460408051600160e01b63abe191c102815260048101849052602481018a905260448101899052905193955091936060936001600160a01b039092169263abe191c19260648083019392829003018186803b158015612ffc57600080fd5b505afa158015613010573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561303957600080fd5b810190808051600160201b81111561305057600080fd5b8201602081018481111561306357600080fd5b81518560208202830111600160201b8211171561307f57600080fd5b50909450600093505050505b81518110156131115760008282815181106130a257fe5b6020908102919091018101516001600160a01b0381166000908152600a880190925260409091205490915060ff161580156130f857506001600160a01b0381166000908152600b8601602052604090205460ff16155b156131085761310881868b613d8c565b5060010161308b565b5050505050505050565b6060600380548060200260200160405190810160405280929190818152602001828054801561317357602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613155575b5050505050905090565b600160d91b6420a226a4a70261319381336139ca565b6131d55760408051600160e51b62461bcd02815260206004820152601260248201526000805160206149a6833981519152604482015290519081900360640190fd5b6111df8484600380548060200260200160405190810160405280929190818152602001828054801561323057602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613212575b5050505050855b600160d91b6420a226a4a70261324d81336139ca565b61328f5760408051600160e51b62461bcd02815260206004820152601260248201526000805160206149a6833981519152604482015290519081900360640190fd5b600754604080517fff0b9c9000000000000000000000000000000000000000000000000000000000815290516000926001600160a01b03169163ff0b9c9091600480830192602092919082900301818787803b1580156132ee57600080fd5b505af1158015613302573d6000803e3d6000fd5b505050506040513d602081101561331857600080fd5b50519050612b2c8686838787614118565b60608060608060608060028054905087106133845760408051600160e51b62461bcd0281526020600482015260106024820152600160821b6f125b9d985b1a5908191a5d9a59195b9902604482015290519081900360640190fd5b60006002888154811061339357fe5b600091825260208220600e90910201805460075460408051600160e11b631faa9ac302815260048101849052905193955091936001600160a01b0390911692633f553586926024808201939291829003018186803b1580156133f457600080fd5b505afa158015613408573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561343157600080fd5b810190808051600160201b81111561344857600080fd5b8201602081018481111561345b57600080fd5b81518560208202830111600160201b8211171561347757600080fd5b5050929190505050975087516040519080825280602002602001820160405280156134ac578160200160208202803883390190505b50965087516040519080825280602002602001820160405280156134da578160200160208202803883390190505b5095508751604051908082528060200260200182016040528015613508578160200160208202803883390190505b5094508751604051908082528060200260200182016040528015613536578160200160208202803883390190505b5093508751604051908082528060200260200182016040528015613564578160200160208202803883390190505b50925060005b88518110156138655782600a0160008a838151811061358557fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060009054906101000a900460ff168882815181106135c757fe5b60200260200101901515908115158152505082600b0160008a83815181106135eb57fe5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060009054906101000a900460ff1687828151811061362d57fe5b9115156020928302919091019091015260075489516001600160a01b0390911690634ee2cd7e908b908490811061366057fe5b602002602001015185600001546040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b031681526020018281526020019250505060206040518083038186803b1580156136ba57600080fd5b505afa1580156136ce573d6000803e3d6000fd5b505050506040513d60208110156136e457600080fd5b505184518590839081106136f457fe5b60200260200101818152505086818151811061370c57fe5b602002602001015161385d5787818151811061372457fe5b6020026020010151156137f65782600c0160008a838151811061374357fe5b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000205486828151811061377857fe5b6020026020010181815250506137d986828151811061379357fe5b60200260200101516137cd8560060154611a8787600401548987815181106137b757fe5b6020026020010151613fc890919063ffffffff16565b9063ffffffff613f0d16565b8582815181106137e557fe5b60200260200101818152505061385d565b6000806138168c8c858151811061380957fe5b602002602001015161190e565b915091508088848151811061382757fe5b6020908102919091010152613842828263ffffffff613f0d16565b87848151811061384e57fe5b60200260200101818152505050505b60010161356a565b50505091939550919395565b60075460408051600160e01b63660d0d6702815290516000926001600160a01b03169163660d0d67916004808301926020929190829003018186803b1580156138b957600080fd5b505afa1580156138cd573d6000803e3d6000fd5b505050506040513d60208110156138e357600080fd5b5051905090565b6000600160c11b6727a822a920aa27a90261390581336139ca565b6139475760408051600160e51b62461bcd02815260206004820152601260248201526000805160206149a6833981519152604482015290519081900360640190fd5b600760009054906101000a90046001600160a01b03166001600160a01b031663ff0b9c906040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561399757600080fd5b505af11580156139ab573d6000803e3d6000fd5b505050506040513d60208110156139c157600080fd5b505191505b5090565b600080600760009054906101000a90046001600160a01b03166001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b158015613a1b57600080fd5b505afa158015613a2f573d6000803e3d6000fd5b505050506040513d6020811015613a4557600080fd5b50516006546001600160a01b038581169281168314935016148180613a675750805b80613af7575060075460408051600160e01b638658b8b90281526001600160a01b0387811660048301523060248301526044820189905291519190921691638658b8b9916064808301926020929190829003018186803b158015613aca57600080fd5b505afa158015613ade573d6000803e3d6000fd5b505050506040513d6020811015613af457600080fd5b50515b95945050505050565b600760009054906101000a90046001600160a01b03166001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b158015613b4e57600080fd5b505afa158015613b62573d6000803e3d6000fd5b505050506040513d6020811015613b7857600080fd5b50516001600160a01b0316331461172d5760408051600160e51b62461bcd02815260206004820152601360248201527f53656e646572206973206e6f74206f776e657200000000000000000000000000604482015290519081900360640190fd5b6002548110613c285760408051600160e51b62461bcd0281526020600482015260106024820152600160821b6f125b9d985b1a5908191a5d9a59195b9902604482015290519081900360640190fd5b60028181548110613c3557fe5b600091825260209091206007600e90920201015460ff1615613ca15760408051600160e51b62461bcd02815260206004820152601260248201527f4469766964656e64207265636c61696d65640000000000000000000000000000604482015290519081900360640190fd5b60028181548110613cae57fe5b90600052602060002090600e020160020154421015613d175760408051600160e51b62461bcd02815260206004820152601b60248201527f4469766964656e64206d6174757269747920696e206675747572650000000000604482015290519081900360640190fd5b60028181548110613d2457fe5b90600052602060002090600e02016003015442106112205760408051600160e51b62461bcd02815260206004820152601760248201527f4469766964656e642065787069727920696e2070617374000000000000000000604482015290519081900360640190fd5b600080613d99838661190e565b6001600160a01b0387166000908152600a870160205260408120805460ff191660011790559193509150613dd3838363ffffffff613f0d16565b6040519091506001600160a01b0387169082156108fc029083906000818181858888f1935050505015613ea7576005850154613e15908463ffffffff61491416565b60058601558115613e58576008850154613e35908363ffffffff61491416565b60088601556001600160a01b0386166000908152600c8601602052604090208290555b83866001600160a01b03167f0cfb57b295d2603fbb329fdc2d35326148368bf26a74cbb525cdf3a71ff5cc3d8585604051808381526020018281526020019250505060405180910390a3612b2c565b6001600160a01b0386166000818152600a87016020908152604091829020805460ff19169055815186815290810185905281518793927fd252e7e7f5d6262d6dd8f80698d23f219cd7847a22b97c199a5984440f3c2715928290030190a3505050505050565b600082821115613f1c57600080fd5b50900390565b600854600160a01b900460ff16613f835760408051600160e51b62461bcd02815260206004820152601660248201527f436f6e7472616374206973206e6f742070617573656400000000000000000000604482015290519081900360640190fd5b60088054600160a01b60ff02191690556040805133815290517faeb196d352664784d1900b0e7414a8face7d29f4dae8c4b0cf68ed477423bbf49181900360200190a1565b600082613fd757506000611908565b82820282848281613fe457fe5b0414613fef57600080fd5b9392505050565b600080821161400457600080fd5b600082848161400f57fe5b04949350505050565b600080546040516001600160a01b03808516939216917f8595877311e370fe3ac87d4f6d12473603393f02ac660e68d2e5e3da5adb610c91a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b600854600160a01b900460ff16156140cd5760408051600160e51b62461bcd0281526020600482015260126024820152600160721b7110dbdb9d1c9858dd081a5cc81c185d5cd95902604482015290519081900360640190fd5b60088054600160a01b60ff021916600160a01b1790556040805133815290517f5ee71a369c8672edded508e624ffc9257fa1ae6886ef32905c18e60196bca3999181900360200190a1565b600154825111156141735760408051600160e51b62461bcd02815260206004820152601b60248201527f546f6f206d616e7920616464726573736573206578636c756465640000000000604482015290519081900360640190fd5b8484116141ca5760408051600160e51b62461bcd02815260206004820152601960248201527f457870697279206973206265666f7265206d6174757269747900000000000000604482015290519081900360640190fd5b4284116142215760408051600160e51b62461bcd02815260206004820152601560248201527f45787069727920697320696e2074686520706173740000000000000000000000604482015290519081900360640190fd5b600034116142795760408051600160e51b62461bcd02815260206004820152601060248201527f4e6f206469766964656e642073656e7400000000000000000000000000000000604482015290519081900360640190fd5b600760009054906101000a90046001600160a01b03166001600160a01b0316635488cc806040518163ffffffff1660e01b815260040160206040518083038186803b1580156142c757600080fd5b505afa1580156142db573d6000803e3d6000fd5b505050506040513d60208110156142f157600080fd5b50518311156142ff57600080fd5b6001600160f81b0319600082901a60f81b1661431a57600080fd5b60025460075460408051600160e41b630981b24d0281526004810187905290516000926001600160a01b03169163981b24d0916024808301926020929190829003018186803b15801561436c57600080fd5b505afa158015614380573d6000803e3d6000fd5b505050506040513d602081101561439657600080fd5b50519050806143e35760408051600160e51b62461bcd02815260206004820152600e6024820152600160901b6d496e76616c696420737570706c7902604482015290519081900360640190fd5b60408051610160810182528681524260208201908152918101898152606082018981523460808401908152600060a0850181815260c0860182815260e08701838152610100880184815261012089018581526101408a018e8152600280546001810182559088529a517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace600e909c029b8c01559a517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf8b015597517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad08a015595517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad189015593517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad288015590517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad3870155517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad486015590517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad58501805460ff191691151591909117905590517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad684015590517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad783015591517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5adb90910155805b85518110156148445760006001600160a01b031686828151811061462257fe5b60200260200101516001600160a01b0316141561467e5760408051600160e51b62461bcd02815260206004820152600f6024820152600160881b6e496e76616c6964206164647265737302604482015290519081900360640190fd5b6002848154811061468b57fe5b90600052602060002090600e0201600b0160008783815181106146aa57fe5b6020908102919091018101516001600160a01b031682528101919091526040016000205460ff16156147265760408051600160e51b62461bcd02815260206004820152601560248201527f6475706564206578636c75646520616464726573730000000000000000000000604482015290519081900360640190fd5b60075486516147da916001600160a01b031690634ee2cd7e9089908590811061474b57fe5b60200260200101518a6040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b031681526020018281526020019250505060206040518083038186803b1580156147a157600080fd5b505afa1580156147b5573d6000803e3d6000fd5b505050506040513d60208110156147cb57600080fd5b5051839063ffffffff61491416565b91506001600285815481106147eb57fe5b90600052602060002090600e0201600b01600088848151811061480a57fe5b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff1916911515919091179055600101614602565b508082116148905760408051600160e51b62461bcd02815260206004820152600e6024820152600160901b6d496e76616c696420737570706c7902604482015290519081900360640190fd5b808203600284815481106148a057fe5b60009182526020918290206006600e909202010191909155604080518881529182018a905281810189905234606083015260808201849052518591859133917f376302a393407da8edbd629bc870b9ae0cca86e0b83dbe5b349854743ab55a53919081900360a00190a45050505050505050565b600082820183811015613fef57600080fd5b82805482825590600052602060002090810192821561497b579160200282015b8281111561497b57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614946565b506139c69261122f9250905b808211156139c65780546001600160a01b031916815560010161498756fe496e76616c6964207065726d697373696f6e00000000000000000000000000006d73672e73656e646572206578636c756465642066726f6d204469766964656e64a165627a7a72305820224c07420b1a9606109af0b36437eeb86393f9c1ca92b04932022fca62a7dbe80029
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _securityToken (address): 0x0000000000000000000000000000000000000000
Arg [1] : _polyToken (address): 0x0000000000000000000000000000000000000000
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000000
Swarm Source
bzzr://224c07420b1a9606109af0b36437eeb86393f9c1ca92b04932022fca62a7dbe8
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.