ETH Price: $2,082.92 (-2.57%)

Contract

0xE4E2a07CB79637Da2736D2bcfFC14dE87fe943eF
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

Please try again later

Advanced mode:
Parent Transaction Hash Method Block
From
To
View All Internal Transactions
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
EtherDividendCheckpoint

Compiler Version
v0.5.8+commit.23d335f2

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
/**
 *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

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"}]

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

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
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.