Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 22 internal transactions
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
CountTransferManagerFactory
Compiler Version
v0.5.8+commit.23d335f2
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity)
/**
*Submitted for verification at Etherscan.io on 2019-07-19
*/
pragma solidity 0.5.8;
/**
* @title Helper library use to compare or validate the semantic versions
*/
library VersionUtils {
function lessThanOrEqual(uint8[] memory _current, uint8[] memory _new) internal pure returns(bool) {
require(_current.length == 3);
require(_new.length == 3);
uint8 i = 0;
for (i = 0; i < _current.length; i++) {
if (_current[i] == _new[i]) continue;
if (_current[i] < _new[i]) return true;
if (_current[i] > _new[i]) return false;
}
return true;
}
function greaterThanOrEqual(uint8[] memory _current, uint8[] memory _new) internal pure returns(bool) {
require(_current.length == 3);
require(_new.length == 3);
uint8 i = 0;
for (i = 0; i < _current.length; i++) {
if (_current[i] == _new[i]) continue;
if (_current[i] > _new[i]) return true;
if (_current[i] < _new[i]) return false;
}
return true;
}
/**
* @notice Used to pack the uint8[] array data into uint24 value
* @param _major Major version
* @param _minor Minor version
* @param _patch Patch version
*/
function pack(uint8 _major, uint8 _minor, uint8 _patch) internal pure returns(uint24) {
return (uint24(_major) << 16) | (uint24(_minor) << 8) | uint24(_patch);
}
/**
* @notice Used to convert packed data into uint8 array
* @param _packedVersion Packed data
*/
function unpack(uint24 _packedVersion) internal pure returns(uint8[] memory) {
uint8[] memory _unpackVersion = new uint8[](3);
_unpackVersion[0] = uint8(_packedVersion >> 16);
_unpackVersion[1] = uint8(_packedVersion >> 8);
_unpackVersion[2] = uint8(_packedVersion);
return _unpackVersion;
}
/**
* @notice Used to packed the KYC data
*/
function packKYC(uint64 _a, uint64 _b, uint64 _c, uint8 _d) internal pure returns(uint256) {
// this function packs 3 uint64 and a uint8 together in a uint256 to save storage cost
// a is rotated left by 136 bits, b is rotated left by 72 bits and c is rotated left by 8 bits.
// rotation pads empty bits with zeroes so now we can safely do a bitwise OR operation to pack
// all the variables together.
return (uint256(_a) << 136) | (uint256(_b) << 72) | (uint256(_c) << 8) | uint256(_d);
}
/**
* @notice Used to convert packed data into KYC data
* @param _packedVersion Packed data
*/
function unpackKYC(uint256 _packedVersion) internal pure returns(uint64 canSendAfter, uint64 canReceiveAfter, uint64 expiryTime, uint8 added) {
canSendAfter = uint64(_packedVersion >> 136);
canReceiveAfter = uint64(_packedVersion >> 72);
expiryTime = uint64(_packedVersion >> 8);
added = uint8(_packedVersion);
}
}
/**
* @title Utility contract for reusable code
*/
library Util {
/**
* @notice Changes a string to upper case
* @param _base String to change
*/
function upper(string memory _base) internal pure returns(string memory) {
bytes memory _baseBytes = bytes(_base);
for (uint i = 0; i < _baseBytes.length; i++) {
bytes1 b1 = _baseBytes[i];
if (b1 >= 0x61 && b1 <= 0x7A) {
b1 = bytes1(uint8(b1) - 32);
}
_baseBytes[i] = b1;
}
return string(_baseBytes);
}
/**
* @notice Changes the string into bytes32
* @param _source String that need to convert into bytes32
*/
/// Notice - Maximum Length for _source will be 32 chars otherwise returned bytes32 value will have lossy value.
function stringToBytes32(string memory _source) internal pure returns(bytes32) {
return bytesToBytes32(bytes(_source), 0);
}
/**
* @notice Changes bytes into bytes32
* @param _b Bytes that need to convert into bytes32
* @param _offset Offset from which to begin conversion
*/
/// Notice - Maximum length for _source will be 32 chars otherwise returned bytes32 value will have lossy value.
function bytesToBytes32(bytes memory _b, uint _offset) internal pure returns(bytes32) {
bytes32 result;
for (uint i = 0; i < _b.length; i++) {
result |= bytes32(_b[_offset + i] & 0xFF) >> (i * 8);
}
return result;
}
/**
* @notice Changes the bytes32 into string
* @param _source that need to convert into string
*/
function bytes32ToString(bytes32 _source) internal pure returns(string memory) {
bytes memory bytesString = new bytes(32);
uint charCount = 0;
uint j = 0;
for (j = 0; j < 32; j++) {
byte char = byte(bytes32(uint(_source) * 2 ** (8 * j)));
if (char != 0) {
bytesString[charCount] = char;
charCount++;
}
}
bytes memory bytesStringTrimmed = new bytes(charCount);
for (j = 0; j < charCount; j++) {
bytesStringTrimmed[j] = bytesString[j];
}
return string(bytesStringTrimmed);
}
/**
* @notice Gets function signature from _data
* @param _data Passed data
* @return bytes4 sig
*/
function getSig(bytes memory _data) internal pure returns(bytes4 sig) {
uint len = _data.length < 4 ? _data.length : 4;
for (uint256 i = 0; i < len; i++) {
sig |= bytes4(_data[i] & 0xFF) >> (i * 8);
}
return sig;
}
}
/**
* @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);
}
interface IOracle {
/**
* @notice Returns address of oracle currency (0x0 for ETH)
*/
function getCurrencyAddress() external view returns(address currency);
/**
* @notice Returns symbol of oracle currency (0x0 for ETH)
*/
function getCurrencySymbol() external view returns(bytes32 symbol);
/**
* @notice Returns denomination of price
*/
function getCurrencyDenominated() external view returns(bytes32 denominatedCurrency);
/**
* @notice Returns price - should throw if not valid
*/
function getPrice() external returns(uint256 price);
}
interface IPolymathRegistry {
event ChangeAddress(string _nameKey, address indexed _oldAddress, address indexed _newAddress);
/**
* @notice Returns the contract address
* @param _nameKey is the key for the contract address mapping
* @return address
*/
function getAddress(string calldata _nameKey) external view returns(address registryAddress);
/**
* @notice Changes the contract address
* @param _nameKey is the key for the contract address mapping
* @param _newAddress is the new contract address
*/
function changeAddress(string calldata _nameKey, address _newAddress) external;
}
/**
* @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;
}
/**
* @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 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 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;
}
}
library DecimalMath {
using SafeMath for uint256;
uint256 internal constant e18 = uint256(10) ** uint256(18);
/**
* @notice This function multiplies two decimals represented as (decimal * 10**DECIMALS)
* @return uint256 Result of multiplication represented as (decimal * 10**DECIMALS)
*/
function mul(uint256 x, uint256 y) internal pure returns(uint256 z) {
z = SafeMath.add(SafeMath.mul(x, y), (e18) / 2) / (e18);
}
/**
* @notice This function divides two decimals represented as (decimal * 10**DECIMALS)
* @return uint256 Result of division represented as (decimal * 10**DECIMALS)
*/
function div(uint256 x, uint256 y) internal pure returns(uint256 z) {
z = SafeMath.add(SafeMath.mul(x, (e18)), y / 2) / y;
}
}
/**
* @title Interface that any module factory contract should implement
* @notice Contract is abstract
*/
contract ModuleFactory is IModuleFactory, Ownable {
IPolymathRegistry public polymathRegistry;
string initialVersion;
bytes32 public name;
string public title;
string public description;
uint8[] typesData;
bytes32[] tagsData;
bool public isCostInPoly;
uint256 public setupCost;
string constant POLY_ORACLE = "StablePolyUsdOracle";
// @notice Allow only two variables to be stored
// 1. lowerBound
// 2. upperBound
// @dev (0.0.0 will act as the wildcard)
// @dev uint24 consists packed value of uint8 _major, uint8 _minor, uint8 _patch
mapping(string => uint24) compatibleSTVersionRange;
/**
* @notice Constructor
*/
constructor(uint256 _setupCost, address _polymathRegistry, bool _isCostInPoly) public {
setupCost = _setupCost;
polymathRegistry = IPolymathRegistry(_polymathRegistry);
isCostInPoly = _isCostInPoly;
}
/**
* @notice Type of the Module factory
*/
function getTypes() external view returns(uint8[] memory) {
return typesData;
}
/**
* @notice Get the tags related to the module factory
*/
function getTags() external view returns(bytes32[] memory) {
return tagsData;
}
/**
* @notice Get the version related to the module factory
*/
function version() external view returns(string memory) {
return initialVersion;
}
/**
* @notice Used to change the fee of the setup cost
* @param _setupCost new setup cost
*/
function changeSetupCost(uint256 _setupCost) public onlyOwner {
emit ChangeSetupCost(setupCost, _setupCost);
setupCost = _setupCost;
}
/**
* @notice Used to change the currency and amount of setup cost
* @param _setupCost new setup cost
* @param _isCostInPoly new setup cost currency. USD or POLY
*/
function changeCostAndType(uint256 _setupCost, bool _isCostInPoly) public onlyOwner {
emit ChangeSetupCost(setupCost, _setupCost);
emit ChangeCostType(isCostInPoly, _isCostInPoly);
setupCost = _setupCost;
isCostInPoly = _isCostInPoly;
}
/**
* @notice Updates the title of the ModuleFactory
* @param _title New Title that will replace the old one.
*/
function changeTitle(string memory _title) public onlyOwner {
require(bytes(_title).length > 0, "Invalid text");
title = _title;
}
/**
* @notice Updates the description of the ModuleFactory
* @param _description New description that will replace the old one.
*/
function changeDescription(string memory _description) public onlyOwner {
require(bytes(_description).length > 0, "Invalid text");
description = _description;
}
/**
* @notice Updates the name of the ModuleFactory
* @param _name New name that will replace the old one.
*/
function changeName(bytes32 _name) public onlyOwner {
require(_name != bytes32(0), "Invalid text");
name = _name;
}
/**
* @notice Updates the tags of the ModuleFactory
* @param _tagsData New list of tags
*/
function changeTags(bytes32[] memory _tagsData) public onlyOwner {
require(_tagsData.length > 0, "Invalid text");
tagsData = _tagsData;
}
/**
* @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 onlyOwner {
require(
keccak256(abi.encodePacked(_boundType)) == keccak256(abi.encodePacked("lowerBound")) || keccak256(
abi.encodePacked(_boundType)
) == keccak256(abi.encodePacked("upperBound")),
"Invalid bound type"
);
require(_newVersion.length == 3, "Invalid version");
if (compatibleSTVersionRange[_boundType] != uint24(0)) {
uint8[] memory _currentVersion = VersionUtils.unpack(compatibleSTVersionRange[_boundType]);
if (keccak256(abi.encodePacked(_boundType)) == keccak256(abi.encodePacked("lowerBound"))) {
require(VersionUtils.lessThanOrEqual(_newVersion, _currentVersion), "Invalid version");
} else {
require(VersionUtils.greaterThanOrEqual(_newVersion, _currentVersion), "Invalid version");
}
}
compatibleSTVersionRange[_boundType] = VersionUtils.pack(_newVersion[0], _newVersion[1], _newVersion[2]);
emit ChangeSTVersionBound(_boundType, _newVersion[0], _newVersion[1], _newVersion[2]);
}
/**
* @notice Used to get the lower bound
* @return lower bound
*/
function getLowerSTVersionBounds() external view returns(uint8[] memory) {
return VersionUtils.unpack(compatibleSTVersionRange["lowerBound"]);
}
/**
* @notice Used to get the upper bound
* @return upper bound
*/
function getUpperSTVersionBounds() external view returns(uint8[] memory) {
return VersionUtils.unpack(compatibleSTVersionRange["upperBound"]);
}
/**
* @notice Get the setup cost of the module
*/
function setupCostInPoly() public returns (uint256) {
if (isCostInPoly)
return setupCost;
uint256 polyRate = IOracle(polymathRegistry.getAddress(POLY_ORACLE)).getPrice();
return DecimalMath.div(setupCost, polyRate);
}
/**
* @notice Calculates fee in POLY
*/
function _takeFee() internal returns(uint256) {
uint256 polySetupCost = setupCostInPoly();
address polyToken = polymathRegistry.getAddress("PolyToken");
if (polySetupCost > 0) {
require(IERC20(polyToken).transferFrom(msg.sender, owner(), polySetupCost), "Insufficient allowance for module fee");
}
return polySetupCost;
}
/**
* @notice Used to initialize the module
* @param _module Address of module
* @param _data Data used for the intialization of the module factory variables
*/
function _initializeModule(address _module, bytes memory _data) internal {
uint256 polySetupCost = _takeFee();
bytes4 initFunction = IModule(_module).getInitFunction();
if (initFunction != bytes4(0)) {
require(Util.getSig(_data) == initFunction, "Provided data is not valid");
/*solium-disable-next-line security/no-low-level-calls*/
(bool success, ) = _module.call(_data);
require(success, "Unsuccessful initialization");
}
/*solium-disable-next-line security/no-block-members*/
emit GenerateModuleFromFactory(_module, name, address(this), msg.sender, setupCost, polySetupCost);
}
}
/**
* @title Interface for the Polymath Module Registry contract
*/
interface IModuleRegistry {
///////////
// Events
//////////
// Emit when network becomes paused
event Pause(address account);
// Emit when network becomes unpaused
event Unpause(address account);
// Emit when Module is used by the SecurityToken
event ModuleUsed(address indexed _moduleFactory, address indexed _securityToken);
// Emit when the Module Factory gets registered on the ModuleRegistry contract
event ModuleRegistered(address indexed _moduleFactory, address indexed _owner);
// Emit when the module gets verified by Polymath
event ModuleVerified(address indexed _moduleFactory);
// Emit when the module gets unverified by Polymath or the factory owner
event ModuleUnverified(address indexed _moduleFactory);
// Emit when a ModuleFactory is removed by Polymath
event ModuleRemoved(address indexed _moduleFactory, address indexed _decisionMaker);
// Emit when ownership gets transferred
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @notice Called by a security token (2.x) to notify the registry it is using a module
* @param _moduleFactory is the address of the relevant module factory
*/
function useModule(address _moduleFactory) external;
/**
* @notice Called by a security token to notify the registry it is using a module
* @param _moduleFactory is the address of the relevant module factory
* @param _isUpgrade whether the use is part of an existing module upgrade
*/
function useModule(address _moduleFactory, bool _isUpgrade) external;
/**
* @notice Called by the ModuleFactory owner to register new modules for SecurityToken to use
* @param _moduleFactory is the address of the module factory to be registered
*/
function registerModule(address _moduleFactory) external;
/**
* @notice Called by the ModuleFactory owner or registry curator to delete a ModuleFactory
* @param _moduleFactory is the address of the module factory to be deleted
*/
function removeModule(address _moduleFactory) external;
/**
* @notice Check that a module and its factory are compatible
* @param _moduleFactory is the address of the relevant module factory
* @param _securityToken is the address of the relevant security token
* @return bool whether module and token are compatible
*/
function isCompatibleModule(address _moduleFactory, address _securityToken) external view returns(bool isCompatible);
/**
* @notice Called by Polymath to verify modules for SecurityToken to use.
* @notice A module can not be used by an ST unless first approved/verified by Polymath
* @notice (The only exception to this is that the author of the module is the owner of the ST - Only if enabled by the FeatureRegistry)
* @param _moduleFactory is the address of the module factory to be registered
*/
function verifyModule(address _moduleFactory) external;
/**
* @notice Called by Polymath to unverify modules for SecurityToken to use.
* @notice A module can not be used by an ST unless first approved/verified by Polymath
* @notice (The only exception to this is that the author of the module is the owner of the ST - Only if enabled by the FeatureRegistry)
* @param _moduleFactory is the address of the module factory to be registered
*/
function unverifyModule(address _moduleFactory) external;
/**
* @notice Returns the verified status, and reputation of the entered Module Factory
* @param _factoryAddress is the address of the module factory
* @return bool indicating whether module factory is verified
* @return address of the factory owner
* @return address array which contains the list of securityTokens that use that module factory
*/
function getFactoryDetails(address _factoryAddress) external view returns(bool isVerified, address factoryOwner, address[] memory usingTokens);
/**
* @notice Returns all the tags related to the a module type which are valid for the given token
* @param _moduleType is the module type
* @param _securityToken is the token
* @return list of tags
* @return corresponding list of module factories
*/
function getTagsByTypeAndToken(uint8 _moduleType, address _securityToken) external view returns(bytes32[] memory tags, address[] memory factories);
/**
* @notice Returns all the tags related to the a module type which are valid for the given token
* @param _moduleType is the module type
* @return list of tags
* @return corresponding list of module factories
*/
function getTagsByType(uint8 _moduleType) external view returns(bytes32[] memory tags, address[] memory factories);
/**
* @notice Returns the list of addresses of all Module Factory of a particular type
* @param _moduleType Type of Module
* @return address array that contains the list of addresses of module factory contracts.
*/
function getAllModulesByType(uint8 _moduleType) external view returns(address[] memory factories);
/**
* @notice Returns the list of addresses of Module Factory of a particular type
* @param _moduleType Type of Module
* @return address array that contains the list of addresses of module factory contracts.
*/
function getModulesByType(uint8 _moduleType) external view returns(address[] memory factories);
/**
* @notice Returns the list of available Module factory addresses of a particular type for a given token.
* @param _moduleType is the module type to look for
* @param _securityToken is the address of SecurityToken
* @return address array that contains the list of available addresses of module factory contracts.
*/
function getModulesByTypeAndToken(uint8 _moduleType, address _securityToken) external view returns(address[] memory factories);
/**
* @notice Use to get the latest contract address of the regstries
*/
function updateFromRegistry() external;
/**
* @notice Get the owner of the contract
* @return address owner
*/
function owner() external view returns(address ownerAddress);
/**
* @notice Check whether the contract operations is paused or not
* @return bool
*/
function isPaused() external view returns(bool paused);
/**
* @notice Reclaims all ERC20Basic compatible tokens
* @param _tokenContract The address of the token contract
*/
function reclaimERC20(address _tokenContract) external;
/**
* @notice Called by the owner to pause, triggers stopped state
*/
function pause() external;
/**
* @notice Called by the owner to unpause, returns to normal state
*/
function unpause() 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 Proxy
* @dev Gives the possibility to delegate any call to a foreign implementation.
*/
contract Proxy {
/**
* @dev Tells the address of the implementation where every call will be delegated.
* @return address of the implementation to which it will be delegated
*/
function _implementation() internal view returns(address);
/**
* @dev Fallback function.
* Implemented entirely in `_fallback`.
*/
function _fallback() internal {
_delegate(_implementation());
}
/**
* @dev Fallback function allowing to perform a delegatecall to the given implementation.
* This function will return whatever the implementation call returns
*/
function _delegate(address implementation) internal {
/*solium-disable-next-line security/no-inline-assembly*/
assembly {
// Copy msg.data. We take full control of memory in this inline assembly
// block because it will not return to Solidity code. We overwrite the
// Solidity scratch pad at memory position 0.
calldatacopy(0, 0, calldatasize)
// Call the implementation.
// out and outsize are 0 because we don't know the size yet.
let result := delegatecall(gas, implementation, 0, calldatasize, 0, 0)
// Copy the returned data.
returndatacopy(0, 0, returndatasize)
switch result
// delegatecall returns 0 on error.
case 0 { revert(0, returndatasize) }
default { return(0, returndatasize) }
}
}
function() external payable {
_fallback();
}
}
/**
* Utility library of inline functions on addresses
*/
library Address {
/**
* Returns whether the target address is a contract
* @dev This function will return false if invoked during the constructor of a contract,
* as the code is not actually created until after the constructor finishes.
* @param account address of the account to check
* @return whether the target address is a contract
*/
function isContract(address account) internal view returns (bool) {
uint256 size;
// XXX Currently there is no better way to check if there is a contract in an address
// than to check the size of the code at that address.
// See https://ethereum.stackexchange.com/a/14016/36603
// for more details about how this works.
// TODO Check this again before the Serenity release, because all addresses will be
// contracts then.
// solhint-disable-next-line no-inline-assembly
assembly { size := extcodesize(account) }
return size > 0;
}
}
/**
* @title UpgradeabilityProxy
* @dev This contract represents a proxy where the implementation address to which it will delegate can be upgraded
*/
contract UpgradeabilityProxy is Proxy {
// Version name of the current implementation
string internal __version;
// Address of the current implementation
address internal __implementation;
/**
* @dev This event will be emitted every time the implementation gets upgraded
* @param _newVersion representing the version name of the upgraded implementation
* @param _newImplementation representing the address of the upgraded implementation
*/
event Upgraded(string _newVersion, address indexed _newImplementation);
/**
* @dev Upgrades the implementation address
* @param _newVersion representing the version name of the new implementation to be set
* @param _newImplementation representing the address of the new implementation to be set
*/
function _upgradeTo(string memory _newVersion, address _newImplementation) internal {
require(
__implementation != _newImplementation && _newImplementation != address(0),
"Old address is not allowed and implementation address should not be 0x"
);
require(Address.isContract(_newImplementation), "Cannot set a proxy implementation to a non-contract address");
require(bytes(_newVersion).length > 0, "Version should not be empty string");
require(keccak256(abi.encodePacked(__version)) != keccak256(abi.encodePacked(_newVersion)), "New version equals to current");
__version = _newVersion;
__implementation = _newImplementation;
emit Upgraded(_newVersion, _newImplementation);
}
}
/**
* @title OwnedUpgradeabilityProxy
* @dev This contract combines an upgradeability proxy with basic authorization control functionalities
*/
contract OwnedUpgradeabilityProxy is UpgradeabilityProxy {
// Owner of the contract
address private __upgradeabilityOwner;
/**
* @dev Event to show ownership has been transferred
* @param _previousOwner representing the address of the previous owner
* @param _newOwner representing the address of the new owner
*/
event ProxyOwnershipTransferred(address _previousOwner, address _newOwner);
/**
* @dev Throws if called by any account other than the owner.
*/
modifier ifOwner() {
if (msg.sender == _upgradeabilityOwner()) {
_;
} else {
_fallback();
}
}
/**
* @dev the constructor sets the original owner of the contract to the sender account.
*/
constructor() public {
_setUpgradeabilityOwner(msg.sender);
}
/**
* @dev Tells the address of the owner
* @return the address of the owner
*/
function _upgradeabilityOwner() internal view returns(address) {
return __upgradeabilityOwner;
}
/**
* @dev Sets the address of the owner
*/
function _setUpgradeabilityOwner(address _newUpgradeabilityOwner) internal {
require(_newUpgradeabilityOwner != address(0), "Address should not be 0x");
__upgradeabilityOwner = _newUpgradeabilityOwner;
}
/**
* @notice Internal function to provide the address of the implementation contract
*/
function _implementation() internal view returns(address) {
return __implementation;
}
/**
* @dev Tells the address of the proxy owner
* @return the address of the proxy owner
*/
function proxyOwner() external ifOwner returns(address) {
return _upgradeabilityOwner();
}
/**
* @dev Tells the version name of the current implementation
* @return string representing the name of the current version
*/
function version() external ifOwner returns(string memory) {
return __version;
}
/**
* @dev Tells the address of the current implementation
* @return address of the current implementation
*/
function implementation() external ifOwner returns(address) {
return _implementation();
}
/**
* @dev Allows the current owner to transfer control of the contract to a newOwner.
* @param _newOwner The address to transfer ownership to.
*/
function transferProxyOwnership(address _newOwner) external ifOwner {
require(_newOwner != address(0), "Address should not be 0x");
emit ProxyOwnershipTransferred(_upgradeabilityOwner(), _newOwner);
_setUpgradeabilityOwner(_newOwner);
}
/**
* @dev Allows the upgradeability owner to upgrade the current version of the proxy.
* @param _newVersion representing the version name of the new implementation to be set.
* @param _newImplementation representing the address of the new implementation to be set.
*/
function upgradeTo(string calldata _newVersion, address _newImplementation) external ifOwner {
_upgradeTo(_newVersion, _newImplementation);
}
/**
* @dev Allows the upgradeability owner to upgrade the current version of the proxy and call the new implementation
* to initialize whatever is needed through a low level call.
* @param _newVersion representing the version name of the new implementation to be set.
* @param _newImplementation representing the address of the new implementation to be set.
* @param _data represents the msg.data to bet sent in the low level call. This parameter may include the function
* signature of the implementation to be called with the needed payload
*/
function upgradeToAndCall(string calldata _newVersion, address _newImplementation, bytes calldata _data) external payable ifOwner {
_upgradeToAndCall(_newVersion, _newImplementation, _data);
}
function _upgradeToAndCall(string memory _newVersion, address _newImplementation, bytes memory _data) internal {
_upgradeTo(_newVersion, _newImplementation);
bool success;
/*solium-disable-next-line security/no-call-value*/
(success, ) = address(this).call.value(msg.value)(_data);
require(success, "Fail in executing the function of implementation contract");
}
}
/**
* @title Factory for deploying upgradable modules
*/
contract UpgradableModuleFactory is ModuleFactory {
event LogicContractSet(string _version, uint256 _upgrade, address _logicContract, bytes _upgradeData);
event ModuleUpgraded(
address indexed _module,
address indexed _securityToken,
uint256 indexed _version
);
struct LogicContract {
string version;
address logicContract;
bytes upgradeData;
}
// Mapping from version to logic contract
mapping (uint256 => LogicContract) public logicContracts;
// Mapping from Security Token address, to deployed proxy module address, to module version
mapping (address => mapping (address => uint256)) public modules;
// Mapping of which security token owns a given module
mapping (address => address) public moduleToSecurityToken;
// Current version
uint256 public latestUpgrade;
/**
* @notice Constructor
* @param _setupCost Setup cost of the module
* @param _logicContract Contract address that contains the logic related to `description`
* @param _polymathRegistry Address of the Polymath registry
* @param _isCostInPoly true = cost in Poly, false = USD
*/
constructor(
string memory _version,
uint256 _setupCost,
address _logicContract,
address _polymathRegistry,
bool _isCostInPoly
)
public ModuleFactory(_setupCost, _polymathRegistry, _isCostInPoly)
{
require(_logicContract != address(0), "Invalid address");
logicContracts[latestUpgrade].logicContract = _logicContract;
logicContracts[latestUpgrade].version = _version;
}
/**
* @notice Used to upgrade the module factory
* @param _version Version of upgraded module
* @param _logicContract Address of deployed module logic contract referenced from proxy
* @param _upgradeData Data to be passed in call to upgradeToAndCall when a token upgrades its module
*/
function setLogicContract(string calldata _version, address _logicContract, bytes calldata _upgradeData) external onlyOwner {
require(keccak256(abi.encodePacked(_version)) != keccak256(abi.encodePacked(logicContracts[latestUpgrade].version)), "Same version");
require(_logicContract != logicContracts[latestUpgrade].logicContract, "Same version");
require(_logicContract != address(0), "Invalid address");
latestUpgrade++;
_modifyLogicContract(latestUpgrade, _version, _logicContract, _upgradeData);
}
/**
* @notice Used to update an existing token logic contract
* @param _upgrade logic contract to upgrade
* @param _version Version of upgraded module
* @param _logicContract Address of deployed module logic contract referenced from proxy
* @param _upgradeData Data to be passed in call to upgradeToAndCall when a token upgrades its module
*/
function updateLogicContract(uint256 _upgrade, string calldata _version, address _logicContract, bytes calldata _upgradeData) external onlyOwner {
require(_upgrade <= latestUpgrade, "Invalid upgrade");
// version & contract must differ from previous version, otherwise upgrade proxy will fail
if (_upgrade > 0) {
require(keccak256(abi.encodePacked(_version)) != keccak256(abi.encodePacked(logicContracts[_upgrade - 1].version)), "Same version");
require(_logicContract != logicContracts[_upgrade - 1].logicContract, "Same version");
}
require(_logicContract != address(0), "Invalid address");
require(_upgradeData.length > 4, "Invalid Upgrade");
_modifyLogicContract(_upgrade, _version, _logicContract, _upgradeData);
}
function _modifyLogicContract(uint256 _upgrade, string memory _version, address _logicContract, bytes memory _upgradeData) internal {
logicContracts[_upgrade].version = _version;
logicContracts[_upgrade].logicContract = _logicContract;
logicContracts[_upgrade].upgradeData = _upgradeData;
IModuleRegistry moduleRegistry = IModuleRegistry(polymathRegistry.getAddress("ModuleRegistry"));
moduleRegistry.unverifyModule(address(this));
emit LogicContractSet(_version, _upgrade, _logicContract, _upgradeData);
}
/**
* @notice Used by a security token to upgrade a given module
* @param _module Address of (proxy) module to be upgraded
*/
function upgrade(address _module) external {
// Only allow the owner of a module to upgrade it
require(moduleToSecurityToken[_module] == msg.sender, "Incorrect caller");
// Only allow issuers to upgrade in single step verisons to preserve upgradeToAndCall semantics
uint256 newVersion = modules[msg.sender][_module] + 1;
require(newVersion <= latestUpgrade, "Incorrect version");
OwnedUpgradeabilityProxy(address(uint160(_module))).upgradeToAndCall(logicContracts[newVersion].version, logicContracts[newVersion].logicContract, logicContracts[newVersion].upgradeData);
modules[msg.sender][_module] = newVersion;
emit ModuleUpgraded(
_module,
msg.sender,
newVersion
);
}
/**
* @notice Used to initialize the module
* @param _module Address of module
* @param _data Data used for the intialization of the module factory variables
*/
function _initializeModule(address _module, bytes memory _data) internal {
super._initializeModule(_module, _data);
moduleToSecurityToken[_module] = msg.sender;
modules[msg.sender][_module] = latestUpgrade;
}
/**
* @notice Get the version related to the module factory
*/
function version() external view returns(string memory) {
return logicContracts[latestUpgrade].version;
}
}
/**
* @title Contract used to store layout for the CountTransferManager storage
*/
contract CountTransferManagerStorage {
// The maximum number of concurrent token holders
uint256 public maxHolderCount;
}
/**
* @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 for all security tokens
*/
interface ISecurityToken {
// Standard ERC20 interface
function symbol() external view returns (string memory);
function name() external view returns (string memory);
function decimals() external view returns(uint8);
function totalSupply() external view returns(uint256);
function balanceOf(address owner) external view returns(uint256);
function allowance(address owner, address spender) external view returns(uint256);
function transfer(address to, uint256 value) external returns(bool);
function transferFrom(address from, address to, uint256 value) external returns(bool);
function approve(address spender, uint256 value) external returns(bool);
function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool);
function increaseAllowance(address spender, uint256 addedValue) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @notice Transfers of securities may fail for a number of reasons. So this function will used to understand the
* cause of failure by getting the byte value. Which will be the ESC that follows the EIP 1066. ESC can be mapped
* with a reson string to understand the failure cause, table of Ethereum status code will always reside off-chain
* @param _to address The address which you want to transfer to
* @param _value uint256 the amount of tokens to be transferred
* @param _data The `bytes _data` allows arbitrary data to be submitted alongside the transfer.
* @return byte Ethereum status code (ESC)
* @return bytes32 Application specific reason code
*/
function canTransfer(address _to, uint256 _value, bytes calldata _data) external view returns (byte statusCode, bytes32 reasonCode);
// Emit at the time when module get added
event ModuleAdded(
uint8[] _types,
bytes32 indexed _name,
address indexed _moduleFactory,
address _module,
uint256 _moduleCost,
uint256 _budget,
bytes32 _label,
bool _archived
);
// Emit when the token details get updated
event UpdateTokenDetails(string _oldDetails, string _newDetails);
// Emit when the token name get updated
event UpdateTokenName(string _oldName, string _newName);
// Emit when the granularity get changed
event GranularityChanged(uint256 _oldGranularity, uint256 _newGranularity);
// Emit when is permanently frozen by the issuer
event FreezeIssuance();
// Emit when transfers are frozen or unfrozen
event FreezeTransfers(bool _status);
// Emit when new checkpoint created
event CheckpointCreated(uint256 indexed _checkpointId, uint256 _investorLength);
// Events to log controller actions
event SetController(address indexed _oldController, address indexed _newController);
//Event emit when the global treasury wallet address get changed
event TreasuryWalletChanged(address _oldTreasuryWallet, address _newTreasuryWallet);
event DisableController();
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
event TokenUpgraded(uint8 _major, uint8 _minor, uint8 _patch);
// Emit when Module get archived from the securityToken
event ModuleArchived(uint8[] _types, address _module); //Event emitted by the tokenLib.
// Emit when Module get unarchived from the securityToken
event ModuleUnarchived(uint8[] _types, address _module); //Event emitted by the tokenLib.
// Emit when Module get removed from the securityToken
event ModuleRemoved(uint8[] _types, address _module); //Event emitted by the tokenLib.
// Emit when the budget allocated to a module is changed
event ModuleBudgetChanged(uint8[] _moduleTypes, address _module, uint256 _oldBudget, uint256 _budget); //Event emitted by the tokenLib.
// Transfer Events
event TransferByPartition(
bytes32 indexed _fromPartition,
address _operator,
address indexed _from,
address indexed _to,
uint256 _value,
bytes _data,
bytes _operatorData
);
// Operator Events
event AuthorizedOperator(address indexed operator, address indexed tokenHolder);
event RevokedOperator(address indexed operator, address indexed tokenHolder);
event AuthorizedOperatorByPartition(bytes32 indexed partition, address indexed operator, address indexed tokenHolder);
event RevokedOperatorByPartition(bytes32 indexed partition, address indexed operator, address indexed tokenHolder);
// Issuance / Redemption Events
event IssuedByPartition(bytes32 indexed partition, address indexed to, uint256 value, bytes data);
event RedeemedByPartition(bytes32 indexed partition, address indexed operator, address indexed from, uint256 value, bytes data, bytes operatorData);
// Document Events
event DocumentRemoved(bytes32 indexed _name, string _uri, bytes32 _documentHash);
event DocumentUpdated(bytes32 indexed _name, string _uri, bytes32 _documentHash);
// Controller Events
event ControllerTransfer(
address _controller,
address indexed _from,
address indexed _to,
uint256 _value,
bytes _data,
bytes _operatorData
);
event ControllerRedemption(
address _controller,
address indexed _tokenHolder,
uint256 _value,
bytes _data,
bytes _operatorData
);
// Issuance / Redemption Events
event Issued(address indexed _operator, address indexed _to, uint256 _value, bytes _data);
event Redeemed(address indexed _operator, address indexed _from, uint256 _value, bytes _data);
/**
* @notice Initialization function
* @dev Expected to be called atomically with the proxy being created, by the owner of the token
* @dev Can only be called once
*/
function initialize(address _getterDelegate) external;
/**
* @notice The standard provides an on-chain function to determine whether a transfer will succeed,
* and return details indicating the reason if the transfer is not valid.
* @param _from The address from whom the tokens get transferred.
* @param _to The address to which to transfer tokens to.
* @param _partition The partition from which to transfer tokens
* @param _value The amount of tokens to transfer from `_partition`
* @param _data Additional data attached to the transfer of tokens
* @return ESC (Ethereum Status Code) following the EIP-1066 standard
* @return Application specific reason codes with additional details
* @return The partition to which the transferred tokens were allocated for the _to address
*/
function canTransferByPartition(
address _from,
address _to,
bytes32 _partition,
uint256 _value,
bytes calldata _data
)
external
view
returns (byte statusCode, bytes32 reasonCode, bytes32 partition);
/**
* @notice Transfers of securities may fail for a number of reasons. So this function will used to understand the
* cause of failure by getting the byte value. Which will be the ESC that follows the EIP 1066. ESC can be mapped
* with a reson string to understand the failure cause, table of Ethereum status code will always reside off-chain
* @param _from address The address which you want to send tokens from
* @param _to address The address which you want to transfer to
* @param _value uint256 the amount of tokens to be transferred
* @param _data The `bytes _data` allows arbitrary data to be submitted alongside the transfer.
* @return byte Ethereum status code (ESC)
* @return bytes32 Application specific reason code
*/
function canTransferFrom(address _from, address _to, uint256 _value, bytes calldata _data) external view returns (byte statusCode, bytes32 reasonCode);
/**
* @notice Used to attach a new document to the contract, or update the URI or hash of an existing attached document
* @dev Can only be executed by the owner of the contract.
* @param _name Name of the document. It should be unique always
* @param _uri Off-chain uri of the document from where it is accessible to investors/advisors to read.
* @param _documentHash hash (of the contents) of the document.
*/
function setDocument(bytes32 _name, string calldata _uri, bytes32 _documentHash) external;
/**
* @notice Used to remove an existing document from the contract by giving the name of the document.
* @dev Can only be executed by the owner of the contract.
* @param _name Name of the document. It should be unique always
*/
function removeDocument(bytes32 _name) external;
/**
* @notice Used to return the details of a document with a known name (`bytes32`).
* @param _name Name of the document
* @return string The URI associated with the document.
* @return bytes32 The hash (of the contents) of the document.
* @return uint256 the timestamp at which the document was last modified.
*/
function getDocument(bytes32 _name) external view returns (string memory documentUri, bytes32 documentHash, uint256 documentTime);
/**
* @notice Used to retrieve a full list of documents attached to the smart contract.
* @return bytes32 List of all documents names present in the contract.
*/
function getAllDocuments() external view returns (bytes32[] memory documentNames);
/**
* @notice In order to provide transparency over whether `controllerTransfer` / `controllerRedeem` are useable
* or not `isControllable` function will be used.
* @dev If `isControllable` returns `false` then it always return `false` and
* `controllerTransfer` / `controllerRedeem` will always revert.
* @return bool `true` when controller address is non-zero otherwise return `false`.
*/
function isControllable() external view returns (bool controlled);
/**
* @notice Checks if an address is a module of certain type
* @param _module Address to check
* @param _type type to check against
*/
function isModule(address _module, uint8 _type) external view returns(bool isValid);
/**
* @notice This function must be called to increase the total supply (Corresponds to mint function of ERC20).
* @dev It only be called by the token issuer or the operator defined by the issuer. ERC1594 doesn't have
* have the any logic related to operator but its superset ERC1400 have the operator logic and this function
* is allowed to call by the operator.
* @param _tokenHolder The account that will receive the created tokens (account should be whitelisted or KYCed).
* @param _value The amount of tokens need to be issued
* @param _data The `bytes _data` allows arbitrary data to be submitted alongside the transfer.
*/
function issue(address _tokenHolder, uint256 _value, bytes calldata _data) external;
/**
* @notice issue new tokens and assigns them to the target _tokenHolder.
* @dev Can only be called by the issuer or STO attached to the token.
* @param _tokenHolders A list of addresses to whom the minted tokens will be dilivered
* @param _values A list of number of tokens get minted and transfer to corresponding address of the investor from _tokenHolders[] list
* @return success
*/
function issueMulti(address[] calldata _tokenHolders, uint256[] calldata _values) external;
/**
* @notice Increases totalSupply and the corresponding amount of the specified owners partition
* @param _partition The partition to allocate the increase in balance
* @param _tokenHolder The token holder whose balance should be increased
* @param _value The amount by which to increase the balance
* @param _data Additional data attached to the minting of tokens
*/
function issueByPartition(bytes32 _partition, address _tokenHolder, uint256 _value, bytes calldata _data) external;
/**
* @notice Decreases totalSupply and the corresponding amount of the specified partition of msg.sender
* @param _partition The partition to allocate the decrease in balance
* @param _value The amount by which to decrease the balance
* @param _data Additional data attached to the burning of tokens
*/
function redeemByPartition(bytes32 _partition, uint256 _value, bytes calldata _data) external;
/**
* @notice This function redeem an amount of the token of a msg.sender. For doing so msg.sender may incentivize
* using different ways that could be implemented with in the `redeem` function definition. But those implementations
* are out of the scope of the ERC1594.
* @param _value The amount of tokens need to be redeemed
* @param _data The `bytes _data` it can be used in the token contract to authenticate the redemption.
*/
function redeem(uint256 _value, bytes calldata _data) external;
/**
* @notice This function redeem an amount of the token of a msg.sender. For doing so msg.sender may incentivize
* using different ways that could be implemented with in the `redeem` function definition. But those implementations
* are out of the scope of the ERC1594.
* @dev It is analogy to `transferFrom`
* @param _tokenHolder The account whose tokens gets redeemed.
* @param _value The amount of tokens need to be redeemed
* @param _data The `bytes _data` it can be used in the token contract to authenticate the redemption.
*/
function redeemFrom(address _tokenHolder, uint256 _value, bytes calldata _data) external;
/**
* @notice Decreases totalSupply and the corresponding amount of the specified partition of tokenHolder
* @dev This function can only be called by the authorised operator.
* @param _partition The partition to allocate the decrease in balance.
* @param _tokenHolder The token holder whose balance should be decreased
* @param _value The amount by which to decrease the balance
* @param _data Additional data attached to the burning of tokens
* @param _operatorData Additional data attached to the transfer of tokens by the operator
*/
function operatorRedeemByPartition(
bytes32 _partition,
address _tokenHolder,
uint256 _value,
bytes calldata _data,
bytes calldata _operatorData
) external;
/**
* @notice Validate permissions with PermissionManager if it exists, If no Permission return false
* @dev Note that IModule withPerm will allow ST owner all permissions anyway
* @dev this allows individual modules to override this logic if needed (to not allow ST owner all permissions)
* @param _delegate address of delegate
* @param _module address of PermissionManager module
* @param _perm the permissions
* @return success
*/
function checkPermission(address _delegate, address _module, bytes32 _perm) external view returns(bool hasPermission);
/**
* @notice Returns module list for a module type
* @param _module Address of the module
* @return bytes32 Name
* @return address Module address
* @return address Module factory address
* @return bool Module archived
* @return uint8 Array of module types
* @return bytes32 Module label
*/
function getModule(address _module) external view returns (bytes32 moduleName, address moduleAddress, address factoryAddress, bool isArchived, uint8[] memory moduleTypes, bytes32 moduleLabel);
/**
* @notice Returns module list for a module name
* @param _name Name of the module
* @return address[] List of modules with this name
*/
function getModulesByName(bytes32 _name) external view returns(address[] memory modules);
/**
* @notice Returns module list for a module type
* @param _type Type of the module
* @return address[] List of modules with this type
*/
function getModulesByType(uint8 _type) external view returns(address[] memory modules);
/**
* @notice use to return the global treasury wallet
*/
function getTreasuryWallet() external view returns(address treasuryWallet);
/**
* @notice Queries totalSupply at a specified checkpoint
* @param _checkpointId Checkpoint ID to query as of
*/
function totalSupplyAt(uint256 _checkpointId) external view returns(uint256 supply);
/**
* @notice Queries balance at a specified checkpoint
* @param _investor Investor to query balance for
* @param _checkpointId Checkpoint ID to query as of
*/
function balanceOfAt(address _investor, uint256 _checkpointId) external view returns(uint256 balance);
/**
* @notice Creates a checkpoint that can be used to query historical balances / totalSuppy
*/
function createCheckpoint() external returns(uint256 checkpointId);
/**
* @notice Gets list of times that checkpoints were created
* @return List of checkpoint times
*/
function getCheckpointTimes() external view returns(uint256[] memory checkpointTimes);
/**
* @notice returns an array of investors
* NB - this length may differ from investorCount as it contains all investors that ever held tokens
* @return list of addresses
*/
function getInvestors() external view returns(address[] memory investors);
/**
* @notice returns an array of investors at a given checkpoint
* NB - this length may differ from investorCount as it contains all investors that ever held tokens
* @param _checkpointId Checkpoint id at which investor list is to be populated
* @return list of investors
*/
function getInvestorsAt(uint256 _checkpointId) external view returns(address[] memory investors);
/**
* @notice returns an array of investors with non zero balance at a given checkpoint
* @param _checkpointId Checkpoint id at which investor list is to be populated
* @param _start Position of investor to start iteration from
* @param _end Position of investor to stop iteration at
* @return list of investors
*/
function getInvestorsSubsetAt(uint256 _checkpointId, uint256 _start, uint256 _end) external view returns(address[] memory investors);
/**
* @notice generates subset of investors
* NB - can be used in batches if investor list is large
* @param _start Position of investor to start iteration from
* @param _end Position of investor to stop iteration at
* @return list of investors
*/
function iterateInvestors(uint256 _start, uint256 _end) external view returns(address[] memory investors);
/**
* @notice Gets current checkpoint ID
* @return Id
*/
function currentCheckpointId() external view returns(uint256 checkpointId);
/**
* @notice Determines whether `_operator` is an operator for all partitions of `_tokenHolder`
* @param _operator The operator to check
* @param _tokenHolder The token holder to check
* @return Whether the `_operator` is an operator for all partitions of `_tokenHolder`
*/
function isOperator(address _operator, address _tokenHolder) external view returns (bool isValid);
/**
* @notice Determines whether `_operator` is an operator for a specified partition of `_tokenHolder`
* @param _partition The partition to check
* @param _operator The operator to check
* @param _tokenHolder The token holder to check
* @return Whether the `_operator` is an operator for a specified partition of `_tokenHolder`
*/
function isOperatorForPartition(bytes32 _partition, address _operator, address _tokenHolder) external view returns (bool isValid);
/**
* @notice Return all partitions
* @param _tokenHolder Whom balance need to queried
* @return List of partitions
*/
function partitionsOf(address _tokenHolder) external view returns (bytes32[] memory partitions);
/**
* @notice Gets data store address
* @return data store address
*/
function dataStore() external view returns (address dataStoreAddress);
/**
* @notice Allows owner to change data store
* @param _dataStore Address of the token data store
*/
function changeDataStore(address _dataStore) external;
/**
* @notice Allows to change the treasury wallet address
* @param _wallet Ethereum address of the treasury wallet
*/
function changeTreasuryWallet(address _wallet) external;
/**
* @notice Allows the owner to withdraw unspent POLY stored by them on the ST or any ERC20 token.
* @dev Owner can transfer POLY to the ST which will be used to pay for modules that require a POLY fee.
* @param _tokenContract Address of the ERC20Basic compliance token
* @param _value Amount of POLY to withdraw
*/
function withdrawERC20(address _tokenContract, uint256 _value) external;
/**
* @notice Allows owner to increase/decrease POLY approval of one of the modules
* @param _module Module address
* @param _change Change in allowance
* @param _increase True if budget has to be increased, false if decrease
*/
function changeModuleBudget(address _module, uint256 _change, bool _increase) external;
/**
* @notice Changes the tokenDetails
* @param _newTokenDetails New token details
*/
function updateTokenDetails(string calldata _newTokenDetails) external;
/**
* @notice Allows owner to change token name
* @param _name new name of the token
*/
function changeName(string calldata _name) external;
/**
* @notice Allows the owner to change token granularity
* @param _granularity Granularity level of the token
*/
function changeGranularity(uint256 _granularity) external;
/**
* @notice Freezes all the transfers
*/
function freezeTransfers() external;
/**
* @notice Un-freezes all the transfers
*/
function unfreezeTransfers() external;
/**
* @notice Permanently freeze issuance of this security token.
* @dev It MUST NOT be possible to increase `totalSuppy` after this function is called.
*/
function freezeIssuance(bytes calldata _signature) external;
/**
* @notice Attachs a module to the SecurityToken
* @dev E.G.: On deployment (through the STR) ST gets a TransferManager module attached to it
* @dev to control restrictions on transfers.
* @param _moduleFactory is the address of the module factory to be added
* @param _data is data packed into bytes used to further configure the module (See STO usage)
* @param _maxCost max amount of POLY willing to pay to the module.
* @param _budget max amount of ongoing POLY willing to assign to the module.
* @param _label custom module label.
* @param _archived whether to add the module as an archived module
*/
function addModuleWithLabel(
address _moduleFactory,
bytes calldata _data,
uint256 _maxCost,
uint256 _budget,
bytes32 _label,
bool _archived
) external;
/**
* @notice Function used to attach a module to the security token
* @dev E.G.: On deployment (through the STR) ST gets a TransferManager module attached to it
* @dev to control restrictions on transfers.
* @dev You are allowed to add a new moduleType if:
* @dev - there is no existing module of that type yet added
* @dev - the last member of the module list is replacable
* @param _moduleFactory is the address of the module factory to be added
* @param _data is data packed into bytes used to further configure the module (See STO usage)
* @param _maxCost max amount of POLY willing to pay to module. (WIP)
* @param _budget max amount of ongoing POLY willing to assign to the module.
* @param _archived whether to add the module as an archived module
*/
function addModule(address _moduleFactory, bytes calldata _data, uint256 _maxCost, uint256 _budget, bool _archived) external;
/**
* @notice Archives a module attached to the SecurityToken
* @param _module address of module to archive
*/
function archiveModule(address _module) external;
/**
* @notice Unarchives a module attached to the SecurityToken
* @param _module address of module to unarchive
*/
function unarchiveModule(address _module) external;
/**
* @notice Removes a module attached to the SecurityToken
* @param _module address of module to archive
*/
function removeModule(address _module) external;
/**
* @notice Used by the issuer to set the controller addresses
* @param _controller address of the controller
*/
function setController(address _controller) external;
/**
* @notice This function allows an authorised address to transfer tokens between any two token holders.
* The transfer must still respect the balances of the token holders (so the transfer must be for at most
* `balanceOf(_from)` tokens) and potentially also need to respect other transfer restrictions.
* @dev This function can only be executed by the `controller` address.
* @param _from Address The address which you want to send tokens from
* @param _to Address The address which you want to transfer to
* @param _value uint256 the amount of tokens to be transferred
* @param _data data to validate the transfer. (It is not used in this reference implementation
* because use of `_data` parameter is implementation specific).
* @param _operatorData data attached to the transfer by controller to emit in event. (It is more like a reason string
* for calling this function (aka force transfer) which provides the transparency on-chain).
*/
function controllerTransfer(address _from, address _to, uint256 _value, bytes calldata _data, bytes calldata _operatorData) external;
/**
* @notice This function allows an authorised address to redeem tokens for any token holder.
* The redemption must still respect the balances of the token holder (so the redemption must be for at most
* `balanceOf(_tokenHolder)` tokens) and potentially also need to respect other transfer restrictions.
* @dev This function can only be executed by the `controller` address.
* @param _tokenHolder The account whose tokens will be redeemed.
* @param _value uint256 the amount of tokens need to be redeemed.
* @param _data data to validate the transfer. (It is not used in this reference implementation
* because use of `_data` parameter is implementation specific).
* @param _operatorData data attached to the transfer by controller to emit in event. (It is more like a reason string
* for calling this function (aka force transfer) which provides the transparency on-chain).
*/
function controllerRedeem(address _tokenHolder, uint256 _value, bytes calldata _data, bytes calldata _operatorData) external;
/**
* @notice Used by the issuer to permanently disable controller functionality
* @dev enabled via feature switch "disableControllerAllowed"
*/
function disableController(bytes calldata _signature) external;
/**
* @notice Used to get the version of the securityToken
*/
function getVersion() external view returns(uint8[] memory version);
/**
* @notice Gets the investor count
*/
function getInvestorCount() external view returns(uint256 investorCount);
/**
* @notice Gets the holder count (investors with non zero balance)
*/
function holderCount() external view returns(uint256 count);
/**
* @notice Overloaded version of the transfer function
* @param _to receiver of transfer
* @param _value value of transfer
* @param _data data to indicate validation
* @return bool success
*/
function transferWithData(address _to, uint256 _value, bytes calldata _data) external;
/**
* @notice Overloaded version of the transferFrom function
* @param _from sender of transfer
* @param _to receiver of transfer
* @param _value value of transfer
* @param _data data to indicate validation
* @return bool success
*/
function transferFromWithData(address _from, address _to, uint256 _value, bytes calldata _data) external;
/**
* @notice Transfers the ownership of tokens from a specified partition from one address to another address
* @param _partition The partition from which to transfer tokens
* @param _to The address to which to transfer tokens to
* @param _value The amount of tokens to transfer from `_partition`
* @param _data Additional data attached to the transfer of tokens
* @return The partition to which the transferred tokens were allocated for the _to address
*/
function transferByPartition(bytes32 _partition, address _to, uint256 _value, bytes calldata _data) external returns (bytes32 partition);
/**
* @notice Get the balance according to the provided partitions
* @param _partition Partition which differentiate the tokens.
* @param _tokenHolder Whom balance need to queried
* @return Amount of tokens as per the given partitions
*/
function balanceOfByPartition(bytes32 _partition, address _tokenHolder) external view returns(uint256 balance);
/**
* @notice Provides the granularity of the token
* @return uint256
*/
function granularity() external view returns(uint256 granularityAmount);
/**
* @notice Provides the address of the polymathRegistry
* @return address
*/
function polymathRegistry() external view returns(address registryAddress);
/**
* @notice Upgrades a module attached to the SecurityToken
* @param _module address of module to archive
*/
function upgradeModule(address _module) external;
/**
* @notice Upgrades security token
*/
function upgradeToken() external;
/**
* @notice A security token issuer can specify that issuance has finished for the token
* (i.e. no new tokens can be minted or issued).
* @dev If a token returns FALSE for `isIssuable()` then it MUST always return FALSE in the future.
* If a token returns FALSE for `isIssuable()` then it MUST never allow additional tokens to be issued.
* @return bool `true` signifies the minting is allowed. While `false` denotes the end of minting
*/
function isIssuable() external view returns (bool issuable);
/**
* @notice Authorises an operator for all partitions of `msg.sender`.
* NB - Allowing investors to authorize an investor to be an operator of all partitions
* but it doesn't mean we operator is allowed to transfer the LOCKED partition values.
* Logic for this restriction is written in `operatorTransferByPartition()` function.
* @param _operator An address which is being authorised.
*/
function authorizeOperator(address _operator) external;
/**
* @notice Revokes authorisation of an operator previously given for all partitions of `msg.sender`.
* NB - Allowing investors to authorize an investor to be an operator of all partitions
* but it doesn't mean we operator is allowed to transfer the LOCKED partition values.
* Logic for this restriction is written in `operatorTransferByPartition()` function.
* @param _operator An address which is being de-authorised
*/
function revokeOperator(address _operator) external;
/**
* @notice Authorises an operator for a given partition of `msg.sender`
* @param _partition The partition to which the operator is authorised
* @param _operator An address which is being authorised
*/
function authorizeOperatorByPartition(bytes32 _partition, address _operator) external;
/**
* @notice Revokes authorisation of an operator previously given for a specified partition of `msg.sender`
* @param _partition The partition to which the operator is de-authorised
* @param _operator An address which is being de-authorised
*/
function revokeOperatorByPartition(bytes32 _partition, address _operator) external;
/**
* @notice Transfers the ownership of tokens from a specified partition from one address to another address
* @param _partition The partition from which to transfer tokens.
* @param _from The address from which to transfer tokens from
* @param _to The address to which to transfer tokens to
* @param _value The amount of tokens to transfer from `_partition`
* @param _data Additional data attached to the transfer of tokens
* @param _operatorData Additional data attached to the transfer of tokens by the operator
* @return The partition to which the transferred tokens were allocated for the _to address
*/
function operatorTransferByPartition(
bytes32 _partition,
address _from,
address _to,
uint256 _value,
bytes calldata _data,
bytes calldata _operatorData
)
external
returns (bytes32 partition);
/*
* @notice Returns if transfers are currently frozen or not
*/
function transfersFrozen() external view returns (bool isFrozen);
/**
* @dev Allows the current owner to transfer control of the contract to a newOwner.
* @param newOwner The address to transfer ownership to.
*/
function transferOwnership(address newOwner) external;
/**
* @return true if `msg.sender` is the owner of the contract.
*/
function isOwner() external view returns (bool);
/**
* @return the address of the owner.
*/
function owner() external view returns (address ownerAddress);
function controller() external view returns(address controllerAddress);
function moduleRegistry() external view returns(address moduleRegistryAddress);
function securityTokenRegistry() external view returns(address securityTokenRegistryAddress);
function polyToken() external view returns(address polyTokenAddress);
function tokenFactory() external view returns(address tokenFactoryAddress);
function getterDelegate() external view returns(address delegate);
function controllerDisabled() external view returns(bool isDisabled);
function initialized() external view returns(bool isInitialized);
function tokenDetails() external view returns(string memory details);
function updateFromRegistry() external;
}
/**
* @title Storage for Module contract
* @notice Contract is abstract
*/
contract ModuleStorage {
address public factory;
ISecurityToken public securityToken;
// Permission flag
bytes32 public constant ADMIN = "ADMIN";
bytes32 public constant OPERATOR = "OPERATOR";
bytes32 internal constant TREASURY = 0xaae8817359f3dcb67d050f44f3e49f982e0359d90ca4b5f18569926304aaece6; // keccak256(abi.encodePacked("TREASURY_WALLET"))
IERC20 public polyToken;
/**
* @notice Constructor
* @param _securityToken Address of the security token
* @param _polyAddress Address of the polytoken
*/
constructor(address _securityToken, address _polyAddress) public {
securityToken = ISecurityToken(_securityToken);
factory = msg.sender;
polyToken = IERC20(_polyAddress);
}
}
/**
* @title CountTransferManager module Proxy
*/
contract CountTransferManagerProxy is CountTransferManagerStorage, ModuleStorage, Pausable, OwnedUpgradeabilityProxy {
/**
* @notice Constructor
* @param _securityToken Address of the security token
* @param _polyAddress Address of the polytoken
* @param _implementation representing the address of the new implementation to be set
*/
constructor (
string memory _version,
address _securityToken,
address _polyAddress,
address _implementation
)
public
ModuleStorage(_securityToken, _polyAddress)
{
require(
_implementation != address(0),
"Implementation address should not be 0x"
);
_upgradeTo(_version, _implementation);
}
}
/**
* @title Factory for deploying CountTransferManager module
*/
contract CountTransferManagerFactory is UpgradableModuleFactory {
/**
* @notice Constructor
* @param _setupCost Setup cost of the module
* @param _logicContract Contract address that contains the logic related to `description`
* @param _polymathRegistry Address of the Polymath registry
* @param _isCostInPoly true = cost in Poly, false = USD
*/
constructor (
uint256 _setupCost,
address _logicContract,
address _polymathRegistry,
bool _isCostInPoly
)
public
UpgradableModuleFactory("3.0.0", _setupCost, _logicContract, _polymathRegistry, _isCostInPoly)
{
name = "CountTransferManager";
title = "Count Transfer Manager";
description = "Restrict the number of investors";
typesData.push(2);
tagsData.push("Count");
tagsData.push("Transfer Restriction");
compatibleSTVersionRange["lowerBound"] = VersionUtils.pack(uint8(3), uint8(0), uint8(0));
compatibleSTVersionRange["upperBound"] = VersionUtils.pack(uint8(3), uint8(0), uint8(0));
}
/**
* @notice Used to launch the Module with the help of factory
* @param _data Data used for the intialization of the module factory variables
* @return address Contract address of the Module
*/
function deploy(bytes calldata _data) external returns(address) {
address countTransferManager = address(new CountTransferManagerProxy(logicContracts[latestUpgrade].version, msg.sender, polymathRegistry.getAddress("PolyToken"), logicContracts[latestUpgrade].logicContract));
_initializeModule(countTransferManager, _data);
return countTransferManager;
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"constant":false,"inputs":[{"name":"_data","type":"bytes"}],"name":"deploy","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_module","type":"address"}],"name":"upgrade","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_setupCost","type":"uint256"}],"name":"changeSetupCost","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_tagsData","type":"bytes32[]"}],"name":"changeTags","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"setupCostInPoly","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_title","type":"string"}],"name":"changeTitle","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_version","type":"string"},{"name":"_logicContract","type":"address"},{"name":"_upgradeData","type":"bytes"}],"name":"setLogicContract","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"isCostInPoly","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"title","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"version","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"latestUpgrade","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"logicContracts","outputs":[{"name":"version","type":"string"},{"name":"logicContract","type":"address"},{"name":"upgradeData","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"description","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"polymathRegistry","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"setupCost","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getLowerSTVersionBounds","outputs":[{"name":"","type":"uint8[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"bytes32"}],"name":"changeName","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getTags","outputs":[{"name":"","type":"bytes32[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"modules","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"moduleToSecurityToken","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getTypes","outputs":[{"name":"","type":"uint8[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_setupCost","type":"uint256"},{"name":"_isCostInPoly","type":"bool"}],"name":"changeCostAndType","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_upgrade","type":"uint256"},{"name":"_version","type":"string"},{"name":"_logicContract","type":"address"},{"name":"_upgradeData","type":"bytes"}],"name":"updateLogicContract","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_description","type":"string"}],"name":"changeDescription","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getUpperSTVersionBounds","outputs":[{"name":"","type":"uint8[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_boundType","type":"string"},{"name":"_newVersion","type":"uint8[]"}],"name":"changeSTVersionBounds","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_setupCost","type":"uint256"},{"name":"_logicContract","type":"address"},{"name":"_polymathRegistry","type":"address"},{"name":"_isCostInPoly","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_version","type":"string"},{"indexed":false,"name":"_upgrade","type":"uint256"},{"indexed":false,"name":"_logicContract","type":"address"},{"indexed":false,"name":"_upgradeData","type":"bytes"}],"name":"LogicContractSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_module","type":"address"},{"indexed":true,"name":"_securityToken","type":"address"},{"indexed":true,"name":"_version","type":"uint256"}],"name":"ModuleUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_oldSetupCost","type":"uint256"},{"indexed":false,"name":"_newSetupCost","type":"uint256"}],"name":"ChangeSetupCost","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_isOldCostInPoly","type":"bool"},{"indexed":false,"name":"_isNewCostInPoly","type":"bool"}],"name":"ChangeCostType","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_module","type":"address"},{"indexed":true,"name":"_moduleName","type":"bytes32"},{"indexed":true,"name":"_moduleFactory","type":"address"},{"indexed":false,"name":"_creator","type":"address"},{"indexed":false,"name":"_setupCost","type":"uint256"},{"indexed":false,"name":"_setupCostInPoly","type":"uint256"}],"name":"GenerateModuleFromFactory","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_boundType","type":"string"},{"indexed":false,"name":"_major","type":"uint8"},{"indexed":false,"name":"_minor","type":"uint8"},{"indexed":false,"name":"_patch","type":"uint8"}],"name":"ChangeSTVersionBound","type":"event"}]Contract Creation Code
60806040523480156200001157600080fd5b5060405160808062004a03833981018060405260808110156200003357600080fd5b50805160208083015160408085015160609095015181518083018352600581527f332e302e3000000000000000000000000000000000000000000000000000000094810194909452600080546001600160a01b031916331780825592519596939593949193919287928792879287928692859285926001600160a01b039190911691907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3600992909255600180546001600160a01b0319166001600160a01b039283161790556008805460ff19169215159290921790915583166200017d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f496e76616c696420616464726573730000000000000000000000000000000000604482015290519081900360640190fd5b600e80546000908152600b6020908152604080832060010180546001600160a01b0319166001600160a01b038916179055925482529190208651620001c59288019062000448565b50507f436f756e745472616e736665724d616e6167657200000000000000000000000060035550506040805180820190915260168082527f436f756e74205472616e73666572204d616e616765720000000000000000000060209092019182526200023593506004925062000448565b506040805180820190915260208082527f526573747269637420746865206e756d626572206f6620696e766573746f72739181019182526200027a9160059162000448565b5060068054600181810190925560208082047ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f018054601f9093166101000a6002810260ff909102199093169290921790915560078054808401825560008281527f436f756e740000000000000000000000000000000000000000000000000000007fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6889283015582549485019092557f5472616e73666572205265737472696374696f6e0000000000000000000000009301929092556200036991600391819062002a2a62000430821b17901c565b604080517f6c6f776572426f756e64000000000000000000000000000000000000000000008152600a808201529051602a91819003919091019020805462ffffff191662ffffff92909216919091179055620003d5600360008062000430602090811b62002a2a17901c565b604080517f7570706572426f756e64000000000000000000000000000000000000000000008152600a81810152905190819003602a019020805462ffffff9290921662ffffff1990921691909117905550620004ed92505050565b60ff90811691811660081b921660101b919091171790565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200048b57805160ff1916838001178555620004bb565b82800160010185558215620004bb579182015b82811115620004bb5782518255916020019190600101906200049e565b50620004c9929150620004cd565b5090565b620004ea91905b80821115620004c95760008155600101620004d4565b90565b61450680620004fd6000396000f3fe60806040523480156200001157600080fd5b5060043610620002135760003560e01c806377282b701162000129578063a76a0cad11620000b1578063e6120413116200007b578063e61204131462000938578063f2fde38b14620009e2578063f78629991462000a0b578063fb9724561462000a155762000213565b8063a76a0cad1462000802578063b4579d60146200082b578063c97767f01462000835578063d26633e0146200085d5762000213565b80638da5cb5b11620000f35780638da5cb5b14620007b35780638f32d59b14620007bd578063995d9ab714620007c7578063a01fe64614620007d15762000213565b806377282b7014620007235780637e363ffa146200072d5780638677768f1462000737578063898855ed14620007935762000213565b80633c1fdaa511620001ad57806360fece01116200017757806360fece0114620005e85780636b68e14414620005f2578063715018a6146200070f5780637284e41614620007195762000213565b80633c1fdaa5146200046a578063436846b8146200053e5780634a79d50c146200055c57806354fd4d5014620005de5762000213565b80630c4c2d8f11620001ef5780630c4c2d8f14620002ef578063265a7218146200030f5780632d0aa22e14620003b65780632dbe07c714620003c05762000213565b8062774360146200021857806306fdde0314620002a85780630900f01014620002c4575b600080fd5b6200028c600480360360208110156200023057600080fd5b810190602081018135600160201b8111156200024b57600080fd5b8201836020820111156200025e57600080fd5b803590602001918460018302840111600160201b831117156200028057600080fd5b50909250905062000adc565b604080516001600160a01b039092168252519081900360200190f35b620002b262000cc5565b60408051918252519081900360200190f35b620002ed60048036036020811015620002dc57600080fd5b50356001600160a01b031662000ccb565b005b620002ed600480360360208110156200030757600080fd5b503562000f99565b620002ed600480360360208110156200032757600080fd5b810190602081018135600160201b8111156200034257600080fd5b8201836020820111156200035557600080fd5b803590602001918460208302840111600160201b831117156200037757600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092955062000fef945050505050565b620002b262001068565b620002ed60048036036020811015620003d857600080fd5b810190602081018135600160201b811115620003f357600080fd5b8201836020820111156200040657600080fd5b803590602001918460018302840111600160201b831117156200042857600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955062001220945050505050565b620002ed600480360360608110156200048257600080fd5b810190602081018135600160201b8111156200049d57600080fd5b820183602082011115620004b057600080fd5b803590602001918460018302840111600160201b83111715620004d257600080fd5b919390926001600160a01b0383351692604081019060200135600160201b811115620004fd57600080fd5b8201836020820111156200051057600080fd5b803590602001918460018302840111600160201b831117156200053257600080fd5b50909250905062001295565b62000548620014fe565b604080519115158252519081900360200190f35b6200056662001507565b6040805160208082528351818301528351919283929083019185019080838360005b83811015620005a257818101518382015260200162000588565b50505050905090810190601f168015620005d05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6200056662001599565b620002b26200163f565b62000612600480360360208110156200060a57600080fd5b503562001645565b6040518080602001846001600160a01b03166001600160a01b0316815260200180602001838103835286818151815260200191508051906020019080838360005b838110156200066d57818101518382015260200162000653565b50505050905090810190601f1680156200069b5780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b83811015620006d0578181015183820152602001620006b6565b50505050905090810190601f168015620006fe5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b620002ed62001792565b62000566620017f0565b6200028c6200184e565b620002b26200185d565b6200074162001863565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156200077f57818101518382015260200162000765565b505050509050019250505060405180910390f35b620002ed60048036036020811015620007ab57600080fd5b5035620018a4565b6200028c62001905565b6200054862001914565b6200074162001925565b620002b260048036036040811015620007e957600080fd5b506001600160a01b03813581169160200135166200197e565b6200028c600480360360208110156200081a57600080fd5b50356001600160a01b03166200199b565b62000741620019b6565b620002ed600480360360408110156200084d57600080fd5b5080359060200135151562001a2d565b620002ed600480360360808110156200087557600080fd5b81359190810190604081016020820135600160201b8111156200089757600080fd5b820183602082011115620008aa57600080fd5b803590602001918460018302840111600160201b83111715620008cc57600080fd5b919390926001600160a01b0383351692604081019060200135600160201b811115620008f757600080fd5b8201836020820111156200090a57600080fd5b803590602001918460018302840111600160201b831117156200092c57600080fd5b50909250905062001adb565b620002ed600480360360208110156200095057600080fd5b810190602081018135600160201b8111156200096b57600080fd5b8201836020820111156200097e57600080fd5b803590602001918460018302840111600160201b83111715620009a057600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955062001dfa945050505050565b620002ed60048036036020811015620009fa57600080fd5b50356001600160a01b031662001e6f565b6200074162001e91565b620002ed6004803603604081101562000a2d57600080fd5b810190602081018135600160201b81111562000a4857600080fd5b82018360208201111562000a5b57600080fd5b803590602001918460018302840111600160201b8311171562000a7d57600080fd5b919390929091602081019035600160201b81111562000a9b57600080fd5b82018360208201111562000aae57600080fd5b803590602001918460208302840111600160201b8311171562000ad057600080fd5b50909250905062001ecd565b600e546000908152600b602090815260408083206001548251600160e01b63bf40fac10281526004810185905260096024820152600160b91b682837b63caa37b5b2b702604482015292518594929333936001600160a01b039093169263bf40fac192606480840193829003018186803b15801562000b5a57600080fd5b505afa15801562000b6f573d6000803e3d6000fd5b505050506040513d602081101562000b8657600080fd5b5051600e546000908152600b6020526040908190206001015490516001600160a01b039091169062000bb89062002ef5565b6001600160a01b0380851660208301528381166040830152821660608201526080808252855460026000196101006001841615020190911604908201819052819060a08201908790801562000c515780601f1062000c255761010080835404028352916020019162000c51565b820191906000526020600020905b81548152906001019060200180831162000c3357829003601f168201915b505095505050505050604051809103906000f08015801562000c77573d6000803e3d6000fd5b50905062000cbc8185858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250620023c592505050565b90505b92915050565b60035481565b6001600160a01b038181166000908152600d602052604090205416331462000d3d5760408051600160e51b62461bcd02815260206004820152601060248201527f496e636f72726563742063616c6c657200000000000000000000000000000000604482015290519081900360640190fd5b336000908152600c602090815260408083206001600160a01b0385168452909152902054600e5460019091019081111562000dc25760408051600160e51b62461bcd02815260206004820152601160248201527f496e636f72726563742076657273696f6e000000000000000000000000000000604482015290519081900360640190fd5b6000818152600b6020526040908190206001808201549251600160e01b63958a41dd0281526001600160a01b03938416602482018190526060600483019081528454600260001995821615610100029590950116849004606484018190529588169563958a41dd959492939285019282916044820191608401908790801562000e8f5780601f1062000e635761010080835404028352916020019162000e8f565b820191906000526020600020905b81548152906001019060200180831162000e7157829003601f168201915b505083810382528454600260001961010060018416150201909116048082526020909101908590801562000f075780601f1062000edb5761010080835404028352916020019162000f07565b820191906000526020600020905b81548152906001019060200180831162000ee957829003601f168201915b505095505050505050600060405180830381600087803b15801562000f2b57600080fd5b505af115801562000f40573d6000803e3d6000fd5b5050336000818152600c602090815260408083206001600160a01b038916808552925280832087905551869550929350917f6b272426dd4b3366b853f4e32bb7fce7392e461688b7a8bf942bd61f756f1d0f9190a45050565b62000fa362001914565b62000fad57600080fd5b600954604080519182526020820183905280517f599b244d21db9af3e5c0ec6cd4af8b4c6085c9ac647c72f008f8c40d0d7cd1be9281900390910190a1600955565b62000ff962001914565b6200100357600080fd5b60008151116200104f5760408051600160e51b62461bcd02815260206004820152600c6024820152600160a21b6b125b9d985b1a59081d195e1d02604482015290519081900360640190fd5b80516200106490600790602084019062002f03565b5050565b60085460009060ff16156200108157506009546200121d565b600154604080518082018252601381527f537461626c65506f6c795573644f7261636c650000000000000000000000000060208083019182529251600160e01b63bf40fac1028152600481019384528251602482015282516000956001600160a01b03169463bf40fac1949390928392604490910191908083838b5b8381101562001117578181015183820152602001620010fd565b50505050905090810190601f168015620011455780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b1580156200116357600080fd5b505afa15801562001178573d6000803e3d6000fd5b505050506040513d60208110156200118f57600080fd5b505160408051600160e11b634c6afee502815290516001600160a01b03909216916398d5fdca916004808201926020929091908290030181600087803b158015620011d957600080fd5b505af1158015620011ee573d6000803e3d6000fd5b505050506040513d60208110156200120557600080fd5b505160095490915062001219908262002418565b9150505b90565b6200122a62001914565b6200123457600080fd5b6000815111620012805760408051600160e51b62461bcd02815260206004820152600c6024820152600160a21b6b125b9d985b1a59081d195e1d02604482015290519081900360640190fd5b80516200106490600490602084019062002f53565b6200129f62001914565b620012a957600080fd5b600b6000600e5481526020019081526020016000206000016040516020018082805460018160011615610100020316600290048015620013235780601f106200130057610100808354040283529182019162001323565b820191906000526020600020905b8154815290600101906020018083116200130e575b5050915050604051602081830303815290604052805190602001208585604051602001808383808284378083019250505092505050604051602081830303815290604052805190602001201415620013b75760408051600160e51b62461bcd02815260206004820152600c6024820152600160a11b6b29b0b6b2903b32b939b4b7b702604482015290519081900360640190fd5b600e546000908152600b60205260409020600101546001600160a01b0384811691161415620014225760408051600160e51b62461bcd02815260206004820152600c6024820152600160a11b6b29b0b6b2903b32b939b4b7b702604482015290519081900360640190fd5b6001600160a01b038316620014765760408051600160e51b62461bcd02815260206004820152600f6024820152600160881b6e496e76616c6964206164647265737302604482015290519081900360640190fd5b600e805460010190819055604080516020601f8801819004810282018101909252868152620014f79291889088908190840183828082843760009201919091525050604080516020601f8901819004810282018101909252878152899350915087908790819084018382808284376000920191909152506200244d92505050565b5050505050565b60085460ff1681565b6004805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015620015915780601f10620015655761010080835404028352916020019162001591565b820191906000526020600020905b8154815290600101906020018083116200157357829003601f168201915b505050505081565b600e546000908152600b602090815260409182902080548351601f6002600019610100600186161502019093169290920491820184900484028101840190945280845260609392830182828015620016355780601f10620016095761010080835404028352916020019162001635565b820191906000526020600020905b8154815290600101906020018083116200161757829003601f168201915b5050505050905090565b600e5481565b600b6020908152600091825260409182902080548351601f60026000196101006001861615020190931692909204918201849004840281018401909452808452909291839190830182828015620016e05780601f10620016b457610100808354040283529160200191620016e0565b820191906000526020600020905b815481529060010190602001808311620016c257829003601f168201915b505050506001838101546002808601805460408051602061010097841615979097026000190190921693909304601f810186900486028201860190935282815295966001600160a01b03909316959294509192830182828015620017885780601f106200175c5761010080835404028352916020019162001788565b820191906000526020600020905b8154815290600101906020018083116200176a57829003601f168201915b5050505050905083565b6200179c62001914565b620017a657600080fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6005805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015620015915780601f10620015655761010080835404028352916020019162001591565b6001546001600160a01b031681565b60095481565b60408051600160b21b691b1bddd95c909bdd5b99028152600a81810152905190819003602a019020546060906200189f9062ffffff16620026f4565b905090565b620018ae62001914565b620018b857600080fd5b80620019005760408051600160e51b62461bcd02815260206004820152600c6024820152600160a21b6b125b9d985b1a59081d195e1d02604482015290519081900360640190fd5b600355565b6000546001600160a01b031690565b6000546001600160a01b0316331490565b606060078054806020026020016040519081016040528092919081815260200182805480156200163557602002820191906000526020600020905b81548152602001906001019080831162001960575050505050905090565b600c60209081526000928352604080842090915290825290205481565b600d602052600090815260409020546001600160a01b031681565b606060068054806020026020016040519081016040528092919081815260200182805480156200163557602002820191906000526020600020906000905b825461010083900a900460ff16815260206001928301818104948501949093039092029101808411620019f45790505050505050905090565b62001a3762001914565b62001a4157600080fd5b600954604080519182526020820184905280517f599b244d21db9af3e5c0ec6cd4af8b4c6085c9ac647c72f008f8c40d0d7cd1be9281900390910190a16008546040805160ff90921615158252821515602083015280517f243562d4d8acd21cf96c899dfa0c26774212a5181e5e40f852c7e6b66b7b96db9281900390910190a16009919091556008805460ff1916911515919091179055565b62001ae562001914565b62001aef57600080fd5b600e5486111562001b4a5760408051600160e51b62461bcd02815260206004820152600f60248201527f496e76616c696420757067726164650000000000000000000000000000000000604482015290519081900360640190fd5b851562001ccd57600b6000600188038152602001908152602001600020600001604051602001808280546001816001161561010002031660029004801562001bcc5780601f1062001ba957610100808354040283529182019162001bcc565b820191906000526020600020905b81548152906001019060200180831162001bb7575b505091505060405160208183030381529060405280519060200120858560405160200180838380828437808301925050509250505060405160208183030381529060405280519060200120141562001c605760408051600160e51b62461bcd02815260206004820152600c6024820152600160a11b6b29b0b6b2903b32b939b4b7b702604482015290519081900360640190fd5b60001986016000908152600b60205260409020600101546001600160a01b038481169116141562001ccd5760408051600160e51b62461bcd02815260206004820152600c6024820152600160a11b6b29b0b6b2903b32b939b4b7b702604482015290519081900360640190fd5b6001600160a01b03831662001d215760408051600160e51b62461bcd02815260206004820152600f6024820152600160881b6e496e76616c6964206164647265737302604482015290519081900360640190fd5b6004811162001d7a5760408051600160e51b62461bcd02815260206004820152600f60248201527f496e76616c696420557067726164650000000000000000000000000000000000604482015290519081900360640190fd5b62001df28686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8901819004810282018101909252878152899350915087908790819084018382808284376000920191909152506200244d92505050565b505050505050565b62001e0462001914565b62001e0e57600080fd5b600081511162001e5a5760408051600160e51b62461bcd02815260206004820152600c6024820152600160a21b6b125b9d985b1a59081d195e1d02604482015290519081900360640190fd5b80516200106490600590602084019062002f53565b62001e7962001914565b62001e8357600080fd5b62001e8e8162002799565b50565b60408051600160b21b691d5c1c195c909bdd5b99028152600a81810152905190819003602a019020546060906200189f9062ffffff16620026f4565b62001ed762001914565b62001ee157600080fd5b6040516020018080600160b21b691b1bddd95c909bdd5b9902815250600a01905060405160208183030381529060405280519060200120848460405160200180838380828437808301925050509250505060405160208183030381529060405280519060200120148062001fb957506040516020018080600160b21b691d5c1c195c909bdd5b9902815250600a01905060405160208183030381529060405280519060200120848460405160200180838380828437808301925050509250505060405160208183030381529060405280519060200120145b6200200e5760408051600160e51b62461bcd02815260206004820152601260248201527f496e76616c696420626f756e6420747970650000000000000000000000000000604482015290519081900360640190fd5b600381146200205c5760408051600160e51b62461bcd02815260206004820152600f6024820152600160891b6e24b73b30b634b2103b32b939b4b7b702604482015290519081900360640190fd5b600062ffffff16600a858560405180838380828437919091019485525050604051928390036020019092205462ffffff16929092149150620022609050576060620020d4600a868660405180838380828437919091019485525050604051928390036020019092205462ffffff169150620026f49050565b90506040516020018080600160b21b691b1bddd95c909bdd5b9902815250600a019050604051602081830303815290604052805190602001208585604051602001808383808284378083019250505092505050604051602081830303815290604052805190602001201415620021d4576200218483838080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525085925062002808915050565b620021ce5760408051600160e51b62461bcd02815260206004820152600f6024820152600160891b6e24b73b30b634b2103b32b939b4b7b702604482015290519081900360640190fd5b6200225e565b620022148383808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508592506200291e915050565b6200225e5760408051600160e51b62461bcd02815260206004820152600f6024820152600160891b6e24b73b30b634b2103b32b939b4b7b702604482015290519081900360640190fd5b505b620022b2828260008181106200227257fe5b9050602002013560ff16838360018181106200228a57fe5b9050602002013560ff1684846002818110620022a257fe5b9050602002013560ff1662002a2a565b600a85856040518083838082843791909101948552505060405192839003602001909220805462ffffff9490941662ffffff1990941693909317909255507f5b67e16edaf7fc70c8d065ea6e70b97ed944d98fe593b04d682216615a3b04db9050848484846000816200232157fe5b9050602002013560ff16858560018181106200233957fe5b9050602002013560ff16868660028181106200235157fe5b9050602002013560ff1660405180806020018560ff1660ff1681526020018460ff1660ff1681526020018360ff1660ff1681526020018281038252878782818152602001925080828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b620023d1828262002a42565b506001600160a01b03166000818152600d6020908152604080832080546001600160a01b03191633908117909155600e54908452600c835281842094845293909152902055565b6000816200243d6200243385670de0b6b3a764000062002ca5565b6002850462002cd0565b816200244557fe5b049392505050565b6000848152600b6020908152604090912084516200246e9286019062002f53565b506000848152600b602090815260409091206001810180546001600160a01b0319166001600160a01b0386161790558251620024b39260029092019184019062002f53565b5060015460408051600160e01b63bf40fac1028152602060048201819052600e60248301527f4d6f64756c655265676973747279000000000000000000000000000000000000604483015291516000936001600160a01b03169263bf40fac19260648082019391829003018186803b1580156200252f57600080fd5b505afa15801562002544573d6000803e3d6000fd5b505050506040513d60208110156200255b57600080fd5b505160408051600160e01b63cf5f591d02815230600482015290519192506001600160a01b0383169163cf5f591d9160248082019260009290919082900301818387803b158015620025ac57600080fd5b505af1158015620025c1573d6000803e3d6000fd5b505050507fbcda874f53511fb6338990baf12d53b3bcef8cb0247ba5f7673450267395515a848685856040518080602001858152602001846001600160a01b03166001600160a01b0316815260200180602001838103835287818151815260200191508051906020019080838360005b838110156200264b57818101518382015260200162002631565b50505050905090810190601f168015620026795780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b83811015620026ae57818101518382015260200162002694565b50505050905090810190601f168015620026dc5780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390a15050505050565b6040805160038082526080820190925260609182919060208201838038833901905050905060108362ffffff16901c816000815181106200273157fe5b602002602001019060ff16908160ff168152505060088362ffffff16901c816001815181106200275d57fe5b602002602001019060ff16908160ff168152505082816002815181106200278057fe5b60ff909216602092830291909101909101529050919050565b6001600160a01b038116620027ad57600080fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b600082516003146200281957600080fd5b81516003146200282857600080fd5b60005b83518160ff1610156200291457828160ff16815181106200284857fe5b602002602001015160ff16848260ff16815181106200286357fe5b602002602001015160ff1614156200287b576200290b565b828160ff16815181106200288b57fe5b602002602001015160ff16848260ff1681518110620028a657fe5b602002602001015160ff161015620028c357600191505062000cbf565b828160ff1681518110620028d357fe5b602002602001015160ff16848260ff1681518110620028ee57fe5b602002602001015160ff1611156200290b57600091505062000cbf565b6001016200282b565b5060019392505050565b600082516003146200292f57600080fd5b81516003146200293e57600080fd5b60005b83518160ff1610156200291457828160ff16815181106200295e57fe5b602002602001015160ff16848260ff16815181106200297957fe5b602002602001015160ff161415620029915762002a21565b828160ff1681518110620029a157fe5b602002602001015160ff16848260ff1681518110620029bc57fe5b602002602001015160ff161115620029d957600191505062000cbf565b828160ff1681518110620029e957fe5b602002602001015160ff16848260ff168151811062002a0457fe5b602002602001015160ff16101562002a2157600091505062000cbf565b60010162002941565b60ff90811691811660081b921660101b919091171790565b600062002a4e62002ce3565b90506000836001600160a01b0316631613ec9d6040518163ffffffff1660e01b815260040160206040518083038186803b15801562002a8c57600080fd5b505afa15801562002aa1573d6000803e3d6000fd5b505050506040513d602081101562002ab857600080fd5b505190506001600160e01b031981161562002c46576001600160e01b0319811662002ae38462002e90565b6001600160e01b0319161462002b435760408051600160e51b62461bcd02815260206004820152601a60248201527f50726f76696465642064617461206973206e6f742076616c6964000000000000604482015290519081900360640190fd5b6000846001600160a01b0316846040518082805190602001908083835b6020831062002b815780518252601f19909201916020918201910162002b60565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811462002be5576040519150601f19603f3d011682016040523d82523d6000602084013e62002bea565b606091505b505090508062002c445760408051600160e51b62461bcd02815260206004820152601b60248201527f556e7375636365737366756c20696e697469616c697a6174696f6e0000000000604482015290519081900360640190fd5b505b600354600954604080516001600160a01b03881681523360208201528082019290925260608201859052513092917fb68b4973fbce93f056103272c1f3f53b607527138d7e323b7b94f7ac169ebf77919081900360800190a350505050565b60008262002cb65750600062000cbf565b8282028284828162002cc457fe5b041462000cbc57600080fd5b60008282018381101562000cbc57600080fd5b60008062002cf062001068565b60015460408051600160e01b63bf40fac102815260206004820181905260096024830152600160b91b682837b63caa37b5b2b702604483015291519394506000936001600160a01b039093169263bf40fac192606480840193919291829003018186803b15801562002d6157600080fd5b505afa15801562002d76573d6000803e3d6000fd5b505050506040513d602081101562002d8d57600080fd5b50519050811562002e8a57806001600160a01b03166323b872dd3362002db262001905565b856040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b031681526020018281526020019350505050602060405180830381600087803b15801562002e1c57600080fd5b505af115801562002e31573d6000803e3d6000fd5b505050506040513d602081101562002e4857600080fd5b505162002e8a57604051600160e51b62461bcd028152600401808060200182810382526025815260200180620044b66025913960400191505060405180910390fd5b50905090565b600080600483511062002ea557600462002ea8565b82515b905060005b8181101562002eee578060080284828151811062002ec757fe5b01602001516001600160f81b031960f891821c90911b16901c929092179160010162002ead565b5050919050565b6114d38062002fe383390190565b82805482825590600052602060002090810192821562002f41579160200282015b8281111562002f4157825182559160200191906001019062002f24565b5062002f4f92915062002fc5565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1062002f9657805160ff191683800117855562002f41565b8280016001018555821562002f41579182018281111562002f4157825182559160200191906001019062002f24565b6200121d91905b8082111562002f4f576000815560010162002fcc56fe608060405260038054600160a01b60ff02191690553480156200002157600080fd5b50604051620014d3380380620014d3833981018060405260808110156200004757600080fd5b8101908080516401000000008111156200006057600080fd5b820160208101848111156200007457600080fd5b81516401000000008111828201871017156200008f57600080fd5b50506020808301516040840151606090940151600280546001600160a01b038085166001600160a01b03199283161790925560018054821633908117909155600380549389169390921692909217905593965090945091620000f59162000172811b901c565b6001600160a01b03811662000156576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260278152602001806200142b6027913960400191505060405180910390fd5b6200016884826200020a60201b60201c565b505050506200062c565b6001600160a01b038116620001e857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f416464726573732073686f756c64206e6f742062652030780000000000000000604482015290519081900360640190fd5b600680546001600160a01b0319166001600160a01b0392909216919091179055565b6005546001600160a01b038281169116148015906200023157506001600160a01b03811615155b62000288576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526046815260200180620014526046913960600191505060405180910390fd5b6200029e816200058160201b62000c271760201c565b620002f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b81526020018062001498603b913960400191505060405180910390fd5b600082511162000351576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180620014096022913960400191505060405180910390fd5b816040516020018082805190602001908083835b60208310620003865780518252601f19909201916020918201910162000365565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012060046040516020018082805460018160011615610100020316600290048015620004255780601f106200040257610100808354040283529182019162000425565b820191906000526020600020905b81548152906001019060200180831162000410575b5050915050604051602081830303815290604052805190602001201415620004ae57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4e65772076657273696f6e20657175616c7320746f2063757272656e74000000604482015290519081900360640190fd5b8151620004c390600490602085019062000587565b50600580546001600160a01b0319166001600160a01b03831690811790915560408051602080825285518183015285517f8e05e0e35ff592971ca8b477d4285a33a61ded208d644042667b78693a472f5e938793928392918301919085019080838360005b838110156200054257818101518382015260200162000528565b50505050905090810190601f168015620005705780820380516001836020036101000a031916815260200191505b509250505060405180910390a25050565b3b151590565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620005ca57805160ff1916838001178555620005fa565b82800160010185558215620005fa579182015b82811115620005fa578251825591602001919060010190620005dd565b50620006089291506200060c565b5090565b6200062991905b8082111562000608576000815560010162000613565b90565b610dcd806200063c6000396000f3fe6080604052600436106100c25760003560e01c80636faa22a51161007f578063ae89a29e11610059578063ae89a29e1461036b578063b84dfbd214610380578063c45a015514610395578063f1739cae146103aa576100c2565b80636faa22a514610272578063958a41dd14610287578063983d273714610356576100c2565b8063025313a2146100cc5780632a0acc6a146100fd57806354fd4d50146101245780635a8b1a9f146101ae5780635c60da1b146102345780635c975abb14610249575b6100ca6103dd565b005b3480156100d857600080fd5b506100e16103ef565b604080516001600160a01b039092168252519081900360200190f35b34801561010957600080fd5b5061011261042c565b60408051918252519081900360200190f35b34801561013057600080fd5b5061013961043b565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561017357818101518382015260200161015b565b50505050905090810190601f1680156101a05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156101ba57600080fd5b506100ca600480360360408110156101d157600080fd5b8101906020810181356401000000008111156101ec57600080fd5b8201836020820111156101fe57600080fd5b8035906020019184600183028401116401000000008311171561022057600080fd5b9193509150356001600160a01b03166104f0565b34801561024057600080fd5b506100e1610564565b34801561025557600080fd5b5061025e61058f565b604080519115158252519081900360200190f35b34801561027e57600080fd5b506100e161059f565b6100ca6004803603606081101561029d57600080fd5b8101906020810181356401000000008111156102b857600080fd5b8201836020820111156102ca57600080fd5b803590602001918460018302840111640100000000831117156102ec57600080fd5b919390926001600160a01b038335169260408101906020013564010000000081111561031757600080fd5b82018360208201111561032957600080fd5b8035906020019184600183028401116401000000008311171561034b57600080fd5b5090925090506105ae565b34801561036257600080fd5b50610112610658565b34801561037757600080fd5b5061011261066a565b34801561038c57600080fd5b506100e1610670565b3480156103a157600080fd5b506100e161067f565b3480156103b657600080fd5b506100ca600480360360208110156103cd57600080fd5b50356001600160a01b031661068e565b6103ed6103e8610771565b610780565b565b60006103f96107a4565b6001600160a01b0316336001600160a01b031614156104215761041a6107a4565b9050610429565b6104296103dd565b90565b600160d91b6420a226a4a70281565b60606104456107a4565b6001600160a01b0316336001600160a01b03161415610421576004805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156104e45780601f106104b9576101008083540402835291602001916104e4565b820191906000526020600020905b8154815290600101906020018083116104c757829003601f168201915b50505050509050610429565b6104f86107a4565b6001600160a01b0316336001600160a01b031614156105575761055283838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508592506107b3915050565b61055f565b61055f6103dd565b505050565b600061056e6107a4565b6001600160a01b0316336001600160a01b031614156104215761041a610771565b600354600160a01b900460ff1681565b6003546001600160a01b031681565b6105b66107a4565b6001600160a01b0316336001600160a01b031614156106495761064485858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f880181900481028201810190925286815288935091508690869081908401838280828437600092019190915250610aae92505050565b610651565b6106516103dd565b5050505050565b600160c11b6727a822a920aa27a90281565b60005481565b6002546001600160a01b031681565b6001546001600160a01b031681565b6106966107a4565b6001600160a01b0316336001600160a01b03161415610766576001600160a01b03811661070d5760408051600160e51b62461bcd02815260206004820152601860248201527f416464726573732073686f756c64206e6f742062652030780000000000000000604482015290519081900360640190fd5b7f5a3e66efaa1e445ebd894728a69d6959842ea1e97bd79b892797106e270efcd96107366107a4565b604080516001600160a01b03928316815291841660208301528051918290030190a161076181610ba7565b61076e565b61076e6103dd565b50565b6005546001600160a01b031690565b3660008037600080366000845af43d6000803e80801561079f573d6000f35b3d6000fd5b6006546001600160a01b031690565b6005546001600160a01b038281169116148015906107d957506001600160a01b03811615155b61081757604051600160e51b62461bcd028152600401808060200182810382526046815260200180610d216046913960600191505060405180910390fd5b61082081610c27565b61085e57604051600160e51b62461bcd02815260040180806020018281038252603b815260200180610d67603b913960400191505060405180910390fd5b60008251116108a157604051600160e51b62461bcd028152600401808060200182810382526022815260200180610cc66022913960400191505060405180910390fd5b816040516020018082805190602001908083835b602083106108d45780518252601f1990920191602091820191016108b5565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001206004604051602001808280546001816001161561010002031660029004801561096f5780601f1061094d57610100808354040283529182019161096f565b820191906000526020600020905b81548152906001019060200180831161095b575b50509150506040516020818303038152906040528051906020012014156109e05760408051600160e51b62461bcd02815260206004820152601d60248201527f4e65772076657273696f6e20657175616c7320746f2063757272656e74000000604482015290519081900360640190fd5b81516109f3906004906020850190610c2d565b50600580546001600160a01b0319166001600160a01b03831690811790915560408051602080825285518183015285517f8e05e0e35ff592971ca8b477d4285a33a61ded208d644042667b78693a472f5e938793928392918301919085019080838360005b83811015610a70578181015183820152602001610a58565b50505050905090810190601f168015610a9d5780820380516001836020036101000a031916815260200191505b509250505060405180910390a25050565b610ab883836107b3565b6000306001600160a01b031634836040518082805190602001908083835b60208310610af55780518252601f199092019160209182019101610ad6565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114610b57576040519150601f19603f3d011682016040523d82523d6000602084013e610b5c565b606091505b50508091505080610ba157604051600160e51b62461bcd028152600401808060200182810382526039815260200180610ce86039913960400191505060405180910390fd5b50505050565b6001600160a01b038116610c055760408051600160e51b62461bcd02815260206004820152601860248201527f416464726573732073686f756c64206e6f742062652030780000000000000000604482015290519081900360640190fd5b600680546001600160a01b0319166001600160a01b0392909216919091179055565b3b151590565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10610c6e57805160ff1916838001178555610c9b565b82800160010185558215610c9b579182015b82811115610c9b578251825591602001919060010190610c80565b50610ca7929150610cab565b5090565b61042991905b80821115610ca75760008155600101610cb156fe56657273696f6e2073686f756c64206e6f7420626520656d70747920737472696e674661696c20696e20657865637574696e67207468652066756e6374696f6e206f6620696d706c656d656e746174696f6e20636f6e74726163744f6c642061646472657373206973206e6f7420616c6c6f77656420616e6420696d706c656d656e746174696f6e20616464726573732073686f756c64206e6f7420626520307843616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e74726163742061646472657373a165627a7a7230582000fe58f7d1b721031cc1ce75379cbd525764e11e35fdb9974d50d71cc6925efd002956657273696f6e2073686f756c64206e6f7420626520656d70747920737472696e67496d706c656d656e746174696f6e20616464726573732073686f756c64206e6f742062652030784f6c642061646472657373206973206e6f7420616c6c6f77656420616e6420696d706c656d656e746174696f6e20616464726573732073686f756c64206e6f7420626520307843616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e74726163742061646472657373496e73756666696369656e7420616c6c6f77616e636520666f72206d6f64756c6520666565a165627a7a72305820be12e0c4ab525aee04b4fc043cf812e84c7ca8e1de337252d90ca8d5f6a2149400290000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efe0078e83cfbd370234f4bd44cba5d64e2ffd5c000000000000000000000000dfabf3e4793cd30affb47ab6fa4cf4eef26bbc270000000000000000000000000000000000000000000000000000000000000001
Deployed Bytecode
0x60806040523480156200001157600080fd5b5060043610620002135760003560e01c806377282b701162000129578063a76a0cad11620000b1578063e6120413116200007b578063e61204131462000938578063f2fde38b14620009e2578063f78629991462000a0b578063fb9724561462000a155762000213565b8063a76a0cad1462000802578063b4579d60146200082b578063c97767f01462000835578063d26633e0146200085d5762000213565b80638da5cb5b11620000f35780638da5cb5b14620007b35780638f32d59b14620007bd578063995d9ab714620007c7578063a01fe64614620007d15762000213565b806377282b7014620007235780637e363ffa146200072d5780638677768f1462000737578063898855ed14620007935762000213565b80633c1fdaa511620001ad57806360fece01116200017757806360fece0114620005e85780636b68e14414620005f2578063715018a6146200070f5780637284e41614620007195762000213565b80633c1fdaa5146200046a578063436846b8146200053e5780634a79d50c146200055c57806354fd4d5014620005de5762000213565b80630c4c2d8f11620001ef5780630c4c2d8f14620002ef578063265a7218146200030f5780632d0aa22e14620003b65780632dbe07c714620003c05762000213565b8062774360146200021857806306fdde0314620002a85780630900f01014620002c4575b600080fd5b6200028c600480360360208110156200023057600080fd5b810190602081018135600160201b8111156200024b57600080fd5b8201836020820111156200025e57600080fd5b803590602001918460018302840111600160201b831117156200028057600080fd5b50909250905062000adc565b604080516001600160a01b039092168252519081900360200190f35b620002b262000cc5565b60408051918252519081900360200190f35b620002ed60048036036020811015620002dc57600080fd5b50356001600160a01b031662000ccb565b005b620002ed600480360360208110156200030757600080fd5b503562000f99565b620002ed600480360360208110156200032757600080fd5b810190602081018135600160201b8111156200034257600080fd5b8201836020820111156200035557600080fd5b803590602001918460208302840111600160201b831117156200037757600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092955062000fef945050505050565b620002b262001068565b620002ed60048036036020811015620003d857600080fd5b810190602081018135600160201b811115620003f357600080fd5b8201836020820111156200040657600080fd5b803590602001918460018302840111600160201b831117156200042857600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955062001220945050505050565b620002ed600480360360608110156200048257600080fd5b810190602081018135600160201b8111156200049d57600080fd5b820183602082011115620004b057600080fd5b803590602001918460018302840111600160201b83111715620004d257600080fd5b919390926001600160a01b0383351692604081019060200135600160201b811115620004fd57600080fd5b8201836020820111156200051057600080fd5b803590602001918460018302840111600160201b831117156200053257600080fd5b50909250905062001295565b62000548620014fe565b604080519115158252519081900360200190f35b6200056662001507565b6040805160208082528351818301528351919283929083019185019080838360005b83811015620005a257818101518382015260200162000588565b50505050905090810190601f168015620005d05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6200056662001599565b620002b26200163f565b62000612600480360360208110156200060a57600080fd5b503562001645565b6040518080602001846001600160a01b03166001600160a01b0316815260200180602001838103835286818151815260200191508051906020019080838360005b838110156200066d57818101518382015260200162000653565b50505050905090810190601f1680156200069b5780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b83811015620006d0578181015183820152602001620006b6565b50505050905090810190601f168015620006fe5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b620002ed62001792565b62000566620017f0565b6200028c6200184e565b620002b26200185d565b6200074162001863565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156200077f57818101518382015260200162000765565b505050509050019250505060405180910390f35b620002ed60048036036020811015620007ab57600080fd5b5035620018a4565b6200028c62001905565b6200054862001914565b6200074162001925565b620002b260048036036040811015620007e957600080fd5b506001600160a01b03813581169160200135166200197e565b6200028c600480360360208110156200081a57600080fd5b50356001600160a01b03166200199b565b62000741620019b6565b620002ed600480360360408110156200084d57600080fd5b5080359060200135151562001a2d565b620002ed600480360360808110156200087557600080fd5b81359190810190604081016020820135600160201b8111156200089757600080fd5b820183602082011115620008aa57600080fd5b803590602001918460018302840111600160201b83111715620008cc57600080fd5b919390926001600160a01b0383351692604081019060200135600160201b811115620008f757600080fd5b8201836020820111156200090a57600080fd5b803590602001918460018302840111600160201b831117156200092c57600080fd5b50909250905062001adb565b620002ed600480360360208110156200095057600080fd5b810190602081018135600160201b8111156200096b57600080fd5b8201836020820111156200097e57600080fd5b803590602001918460018302840111600160201b83111715620009a057600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955062001dfa945050505050565b620002ed60048036036020811015620009fa57600080fd5b50356001600160a01b031662001e6f565b6200074162001e91565b620002ed6004803603604081101562000a2d57600080fd5b810190602081018135600160201b81111562000a4857600080fd5b82018360208201111562000a5b57600080fd5b803590602001918460018302840111600160201b8311171562000a7d57600080fd5b919390929091602081019035600160201b81111562000a9b57600080fd5b82018360208201111562000aae57600080fd5b803590602001918460208302840111600160201b8311171562000ad057600080fd5b50909250905062001ecd565b600e546000908152600b602090815260408083206001548251600160e01b63bf40fac10281526004810185905260096024820152600160b91b682837b63caa37b5b2b702604482015292518594929333936001600160a01b039093169263bf40fac192606480840193829003018186803b15801562000b5a57600080fd5b505afa15801562000b6f573d6000803e3d6000fd5b505050506040513d602081101562000b8657600080fd5b5051600e546000908152600b6020526040908190206001015490516001600160a01b039091169062000bb89062002ef5565b6001600160a01b0380851660208301528381166040830152821660608201526080808252855460026000196101006001841615020190911604908201819052819060a08201908790801562000c515780601f1062000c255761010080835404028352916020019162000c51565b820191906000526020600020905b81548152906001019060200180831162000c3357829003601f168201915b505095505050505050604051809103906000f08015801562000c77573d6000803e3d6000fd5b50905062000cbc8185858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250620023c592505050565b90505b92915050565b60035481565b6001600160a01b038181166000908152600d602052604090205416331462000d3d5760408051600160e51b62461bcd02815260206004820152601060248201527f496e636f72726563742063616c6c657200000000000000000000000000000000604482015290519081900360640190fd5b336000908152600c602090815260408083206001600160a01b0385168452909152902054600e5460019091019081111562000dc25760408051600160e51b62461bcd02815260206004820152601160248201527f496e636f72726563742076657273696f6e000000000000000000000000000000604482015290519081900360640190fd5b6000818152600b6020526040908190206001808201549251600160e01b63958a41dd0281526001600160a01b03938416602482018190526060600483019081528454600260001995821615610100029590950116849004606484018190529588169563958a41dd959492939285019282916044820191608401908790801562000e8f5780601f1062000e635761010080835404028352916020019162000e8f565b820191906000526020600020905b81548152906001019060200180831162000e7157829003601f168201915b505083810382528454600260001961010060018416150201909116048082526020909101908590801562000f075780601f1062000edb5761010080835404028352916020019162000f07565b820191906000526020600020905b81548152906001019060200180831162000ee957829003601f168201915b505095505050505050600060405180830381600087803b15801562000f2b57600080fd5b505af115801562000f40573d6000803e3d6000fd5b5050336000818152600c602090815260408083206001600160a01b038916808552925280832087905551869550929350917f6b272426dd4b3366b853f4e32bb7fce7392e461688b7a8bf942bd61f756f1d0f9190a45050565b62000fa362001914565b62000fad57600080fd5b600954604080519182526020820183905280517f599b244d21db9af3e5c0ec6cd4af8b4c6085c9ac647c72f008f8c40d0d7cd1be9281900390910190a1600955565b62000ff962001914565b6200100357600080fd5b60008151116200104f5760408051600160e51b62461bcd02815260206004820152600c6024820152600160a21b6b125b9d985b1a59081d195e1d02604482015290519081900360640190fd5b80516200106490600790602084019062002f03565b5050565b60085460009060ff16156200108157506009546200121d565b600154604080518082018252601381527f537461626c65506f6c795573644f7261636c650000000000000000000000000060208083019182529251600160e01b63bf40fac1028152600481019384528251602482015282516000956001600160a01b03169463bf40fac1949390928392604490910191908083838b5b8381101562001117578181015183820152602001620010fd565b50505050905090810190601f168015620011455780820380516001836020036101000a031916815260200191505b509250505060206040518083038186803b1580156200116357600080fd5b505afa15801562001178573d6000803e3d6000fd5b505050506040513d60208110156200118f57600080fd5b505160408051600160e11b634c6afee502815290516001600160a01b03909216916398d5fdca916004808201926020929091908290030181600087803b158015620011d957600080fd5b505af1158015620011ee573d6000803e3d6000fd5b505050506040513d60208110156200120557600080fd5b505160095490915062001219908262002418565b9150505b90565b6200122a62001914565b6200123457600080fd5b6000815111620012805760408051600160e51b62461bcd02815260206004820152600c6024820152600160a21b6b125b9d985b1a59081d195e1d02604482015290519081900360640190fd5b80516200106490600490602084019062002f53565b6200129f62001914565b620012a957600080fd5b600b6000600e5481526020019081526020016000206000016040516020018082805460018160011615610100020316600290048015620013235780601f106200130057610100808354040283529182019162001323565b820191906000526020600020905b8154815290600101906020018083116200130e575b5050915050604051602081830303815290604052805190602001208585604051602001808383808284378083019250505092505050604051602081830303815290604052805190602001201415620013b75760408051600160e51b62461bcd02815260206004820152600c6024820152600160a11b6b29b0b6b2903b32b939b4b7b702604482015290519081900360640190fd5b600e546000908152600b60205260409020600101546001600160a01b0384811691161415620014225760408051600160e51b62461bcd02815260206004820152600c6024820152600160a11b6b29b0b6b2903b32b939b4b7b702604482015290519081900360640190fd5b6001600160a01b038316620014765760408051600160e51b62461bcd02815260206004820152600f6024820152600160881b6e496e76616c6964206164647265737302604482015290519081900360640190fd5b600e805460010190819055604080516020601f8801819004810282018101909252868152620014f79291889088908190840183828082843760009201919091525050604080516020601f8901819004810282018101909252878152899350915087908790819084018382808284376000920191909152506200244d92505050565b5050505050565b60085460ff1681565b6004805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015620015915780601f10620015655761010080835404028352916020019162001591565b820191906000526020600020905b8154815290600101906020018083116200157357829003601f168201915b505050505081565b600e546000908152600b602090815260409182902080548351601f6002600019610100600186161502019093169290920491820184900484028101840190945280845260609392830182828015620016355780601f10620016095761010080835404028352916020019162001635565b820191906000526020600020905b8154815290600101906020018083116200161757829003601f168201915b5050505050905090565b600e5481565b600b6020908152600091825260409182902080548351601f60026000196101006001861615020190931692909204918201849004840281018401909452808452909291839190830182828015620016e05780601f10620016b457610100808354040283529160200191620016e0565b820191906000526020600020905b815481529060010190602001808311620016c257829003601f168201915b505050506001838101546002808601805460408051602061010097841615979097026000190190921693909304601f810186900486028201860190935282815295966001600160a01b03909316959294509192830182828015620017885780601f106200175c5761010080835404028352916020019162001788565b820191906000526020600020905b8154815290600101906020018083116200176a57829003601f168201915b5050505050905083565b6200179c62001914565b620017a657600080fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6005805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015620015915780601f10620015655761010080835404028352916020019162001591565b6001546001600160a01b031681565b60095481565b60408051600160b21b691b1bddd95c909bdd5b99028152600a81810152905190819003602a019020546060906200189f9062ffffff16620026f4565b905090565b620018ae62001914565b620018b857600080fd5b80620019005760408051600160e51b62461bcd02815260206004820152600c6024820152600160a21b6b125b9d985b1a59081d195e1d02604482015290519081900360640190fd5b600355565b6000546001600160a01b031690565b6000546001600160a01b0316331490565b606060078054806020026020016040519081016040528092919081815260200182805480156200163557602002820191906000526020600020905b81548152602001906001019080831162001960575050505050905090565b600c60209081526000928352604080842090915290825290205481565b600d602052600090815260409020546001600160a01b031681565b606060068054806020026020016040519081016040528092919081815260200182805480156200163557602002820191906000526020600020906000905b825461010083900a900460ff16815260206001928301818104948501949093039092029101808411620019f45790505050505050905090565b62001a3762001914565b62001a4157600080fd5b600954604080519182526020820184905280517f599b244d21db9af3e5c0ec6cd4af8b4c6085c9ac647c72f008f8c40d0d7cd1be9281900390910190a16008546040805160ff90921615158252821515602083015280517f243562d4d8acd21cf96c899dfa0c26774212a5181e5e40f852c7e6b66b7b96db9281900390910190a16009919091556008805460ff1916911515919091179055565b62001ae562001914565b62001aef57600080fd5b600e5486111562001b4a5760408051600160e51b62461bcd02815260206004820152600f60248201527f496e76616c696420757067726164650000000000000000000000000000000000604482015290519081900360640190fd5b851562001ccd57600b6000600188038152602001908152602001600020600001604051602001808280546001816001161561010002031660029004801562001bcc5780601f1062001ba957610100808354040283529182019162001bcc565b820191906000526020600020905b81548152906001019060200180831162001bb7575b505091505060405160208183030381529060405280519060200120858560405160200180838380828437808301925050509250505060405160208183030381529060405280519060200120141562001c605760408051600160e51b62461bcd02815260206004820152600c6024820152600160a11b6b29b0b6b2903b32b939b4b7b702604482015290519081900360640190fd5b60001986016000908152600b60205260409020600101546001600160a01b038481169116141562001ccd5760408051600160e51b62461bcd02815260206004820152600c6024820152600160a11b6b29b0b6b2903b32b939b4b7b702604482015290519081900360640190fd5b6001600160a01b03831662001d215760408051600160e51b62461bcd02815260206004820152600f6024820152600160881b6e496e76616c6964206164647265737302604482015290519081900360640190fd5b6004811162001d7a5760408051600160e51b62461bcd02815260206004820152600f60248201527f496e76616c696420557067726164650000000000000000000000000000000000604482015290519081900360640190fd5b62001df28686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8901819004810282018101909252878152899350915087908790819084018382808284376000920191909152506200244d92505050565b505050505050565b62001e0462001914565b62001e0e57600080fd5b600081511162001e5a5760408051600160e51b62461bcd02815260206004820152600c6024820152600160a21b6b125b9d985b1a59081d195e1d02604482015290519081900360640190fd5b80516200106490600590602084019062002f53565b62001e7962001914565b62001e8357600080fd5b62001e8e8162002799565b50565b60408051600160b21b691d5c1c195c909bdd5b99028152600a81810152905190819003602a019020546060906200189f9062ffffff16620026f4565b62001ed762001914565b62001ee157600080fd5b6040516020018080600160b21b691b1bddd95c909bdd5b9902815250600a01905060405160208183030381529060405280519060200120848460405160200180838380828437808301925050509250505060405160208183030381529060405280519060200120148062001fb957506040516020018080600160b21b691d5c1c195c909bdd5b9902815250600a01905060405160208183030381529060405280519060200120848460405160200180838380828437808301925050509250505060405160208183030381529060405280519060200120145b6200200e5760408051600160e51b62461bcd02815260206004820152601260248201527f496e76616c696420626f756e6420747970650000000000000000000000000000604482015290519081900360640190fd5b600381146200205c5760408051600160e51b62461bcd02815260206004820152600f6024820152600160891b6e24b73b30b634b2103b32b939b4b7b702604482015290519081900360640190fd5b600062ffffff16600a858560405180838380828437919091019485525050604051928390036020019092205462ffffff16929092149150620022609050576060620020d4600a868660405180838380828437919091019485525050604051928390036020019092205462ffffff169150620026f49050565b90506040516020018080600160b21b691b1bddd95c909bdd5b9902815250600a019050604051602081830303815290604052805190602001208585604051602001808383808284378083019250505092505050604051602081830303815290604052805190602001201415620021d4576200218483838080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525085925062002808915050565b620021ce5760408051600160e51b62461bcd02815260206004820152600f6024820152600160891b6e24b73b30b634b2103b32b939b4b7b702604482015290519081900360640190fd5b6200225e565b620022148383808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508592506200291e915050565b6200225e5760408051600160e51b62461bcd02815260206004820152600f6024820152600160891b6e24b73b30b634b2103b32b939b4b7b702604482015290519081900360640190fd5b505b620022b2828260008181106200227257fe5b9050602002013560ff16838360018181106200228a57fe5b9050602002013560ff1684846002818110620022a257fe5b9050602002013560ff1662002a2a565b600a85856040518083838082843791909101948552505060405192839003602001909220805462ffffff9490941662ffffff1990941693909317909255507f5b67e16edaf7fc70c8d065ea6e70b97ed944d98fe593b04d682216615a3b04db9050848484846000816200232157fe5b9050602002013560ff16858560018181106200233957fe5b9050602002013560ff16868660028181106200235157fe5b9050602002013560ff1660405180806020018560ff1660ff1681526020018460ff1660ff1681526020018360ff1660ff1681526020018281038252878782818152602001925080828437600083820152604051601f909101601f19169092018290039850909650505050505050a150505050565b620023d1828262002a42565b506001600160a01b03166000818152600d6020908152604080832080546001600160a01b03191633908117909155600e54908452600c835281842094845293909152902055565b6000816200243d6200243385670de0b6b3a764000062002ca5565b6002850462002cd0565b816200244557fe5b049392505050565b6000848152600b6020908152604090912084516200246e9286019062002f53565b506000848152600b602090815260409091206001810180546001600160a01b0319166001600160a01b0386161790558251620024b39260029092019184019062002f53565b5060015460408051600160e01b63bf40fac1028152602060048201819052600e60248301527f4d6f64756c655265676973747279000000000000000000000000000000000000604483015291516000936001600160a01b03169263bf40fac19260648082019391829003018186803b1580156200252f57600080fd5b505afa15801562002544573d6000803e3d6000fd5b505050506040513d60208110156200255b57600080fd5b505160408051600160e01b63cf5f591d02815230600482015290519192506001600160a01b0383169163cf5f591d9160248082019260009290919082900301818387803b158015620025ac57600080fd5b505af1158015620025c1573d6000803e3d6000fd5b505050507fbcda874f53511fb6338990baf12d53b3bcef8cb0247ba5f7673450267395515a848685856040518080602001858152602001846001600160a01b03166001600160a01b0316815260200180602001838103835287818151815260200191508051906020019080838360005b838110156200264b57818101518382015260200162002631565b50505050905090810190601f168015620026795780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b83811015620026ae57818101518382015260200162002694565b50505050905090810190601f168015620026dc5780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390a15050505050565b6040805160038082526080820190925260609182919060208201838038833901905050905060108362ffffff16901c816000815181106200273157fe5b602002602001019060ff16908160ff168152505060088362ffffff16901c816001815181106200275d57fe5b602002602001019060ff16908160ff168152505082816002815181106200278057fe5b60ff909216602092830291909101909101529050919050565b6001600160a01b038116620027ad57600080fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b600082516003146200281957600080fd5b81516003146200282857600080fd5b60005b83518160ff1610156200291457828160ff16815181106200284857fe5b602002602001015160ff16848260ff16815181106200286357fe5b602002602001015160ff1614156200287b576200290b565b828160ff16815181106200288b57fe5b602002602001015160ff16848260ff1681518110620028a657fe5b602002602001015160ff161015620028c357600191505062000cbf565b828160ff1681518110620028d357fe5b602002602001015160ff16848260ff1681518110620028ee57fe5b602002602001015160ff1611156200290b57600091505062000cbf565b6001016200282b565b5060019392505050565b600082516003146200292f57600080fd5b81516003146200293e57600080fd5b60005b83518160ff1610156200291457828160ff16815181106200295e57fe5b602002602001015160ff16848260ff16815181106200297957fe5b602002602001015160ff161415620029915762002a21565b828160ff1681518110620029a157fe5b602002602001015160ff16848260ff1681518110620029bc57fe5b602002602001015160ff161115620029d957600191505062000cbf565b828160ff1681518110620029e957fe5b602002602001015160ff16848260ff168151811062002a0457fe5b602002602001015160ff16101562002a2157600091505062000cbf565b60010162002941565b60ff90811691811660081b921660101b919091171790565b600062002a4e62002ce3565b90506000836001600160a01b0316631613ec9d6040518163ffffffff1660e01b815260040160206040518083038186803b15801562002a8c57600080fd5b505afa15801562002aa1573d6000803e3d6000fd5b505050506040513d602081101562002ab857600080fd5b505190506001600160e01b031981161562002c46576001600160e01b0319811662002ae38462002e90565b6001600160e01b0319161462002b435760408051600160e51b62461bcd02815260206004820152601a60248201527f50726f76696465642064617461206973206e6f742076616c6964000000000000604482015290519081900360640190fd5b6000846001600160a01b0316846040518082805190602001908083835b6020831062002b815780518252601f19909201916020918201910162002b60565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811462002be5576040519150601f19603f3d011682016040523d82523d6000602084013e62002bea565b606091505b505090508062002c445760408051600160e51b62461bcd02815260206004820152601b60248201527f556e7375636365737366756c20696e697469616c697a6174696f6e0000000000604482015290519081900360640190fd5b505b600354600954604080516001600160a01b03881681523360208201528082019290925260608201859052513092917fb68b4973fbce93f056103272c1f3f53b607527138d7e323b7b94f7ac169ebf77919081900360800190a350505050565b60008262002cb65750600062000cbf565b8282028284828162002cc457fe5b041462000cbc57600080fd5b60008282018381101562000cbc57600080fd5b60008062002cf062001068565b60015460408051600160e01b63bf40fac102815260206004820181905260096024830152600160b91b682837b63caa37b5b2b702604483015291519394506000936001600160a01b039093169263bf40fac192606480840193919291829003018186803b15801562002d6157600080fd5b505afa15801562002d76573d6000803e3d6000fd5b505050506040513d602081101562002d8d57600080fd5b50519050811562002e8a57806001600160a01b03166323b872dd3362002db262001905565b856040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b031681526020018281526020019350505050602060405180830381600087803b15801562002e1c57600080fd5b505af115801562002e31573d6000803e3d6000fd5b505050506040513d602081101562002e4857600080fd5b505162002e8a57604051600160e51b62461bcd028152600401808060200182810382526025815260200180620044b66025913960400191505060405180910390fd5b50905090565b600080600483511062002ea557600462002ea8565b82515b905060005b8181101562002eee578060080284828151811062002ec757fe5b01602001516001600160f81b031960f891821c90911b16901c929092179160010162002ead565b5050919050565b6114d38062002fe383390190565b82805482825590600052602060002090810192821562002f41579160200282015b8281111562002f4157825182559160200191906001019062002f24565b5062002f4f92915062002fc5565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1062002f9657805160ff191683800117855562002f41565b8280016001018555821562002f41579182018281111562002f4157825182559160200191906001019062002f24565b6200121d91905b8082111562002f4f576000815560010162002fcc56fe608060405260038054600160a01b60ff02191690553480156200002157600080fd5b50604051620014d3380380620014d3833981018060405260808110156200004757600080fd5b8101908080516401000000008111156200006057600080fd5b820160208101848111156200007457600080fd5b81516401000000008111828201871017156200008f57600080fd5b50506020808301516040840151606090940151600280546001600160a01b038085166001600160a01b03199283161790925560018054821633908117909155600380549389169390921692909217905593965090945091620000f59162000172811b901c565b6001600160a01b03811662000156576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260278152602001806200142b6027913960400191505060405180910390fd5b6200016884826200020a60201b60201c565b505050506200062c565b6001600160a01b038116620001e857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f416464726573732073686f756c64206e6f742062652030780000000000000000604482015290519081900360640190fd5b600680546001600160a01b0319166001600160a01b0392909216919091179055565b6005546001600160a01b038281169116148015906200023157506001600160a01b03811615155b62000288576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526046815260200180620014526046913960600191505060405180910390fd5b6200029e816200058160201b62000c271760201c565b620002f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603b81526020018062001498603b913960400191505060405180910390fd5b600082511162000351576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180620014096022913960400191505060405180910390fd5b816040516020018082805190602001908083835b60208310620003865780518252601f19909201916020918201910162000365565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040516020818303038152906040528051906020012060046040516020018082805460018160011615610100020316600290048015620004255780601f106200040257610100808354040283529182019162000425565b820191906000526020600020905b81548152906001019060200180831162000410575b5050915050604051602081830303815290604052805190602001201415620004ae57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4e65772076657273696f6e20657175616c7320746f2063757272656e74000000604482015290519081900360640190fd5b8151620004c390600490602085019062000587565b50600580546001600160a01b0319166001600160a01b03831690811790915560408051602080825285518183015285517f8e05e0e35ff592971ca8b477d4285a33a61ded208d644042667b78693a472f5e938793928392918301919085019080838360005b838110156200054257818101518382015260200162000528565b50505050905090810190601f168015620005705780820380516001836020036101000a031916815260200191505b509250505060405180910390a25050565b3b151590565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620005ca57805160ff1916838001178555620005fa565b82800160010185558215620005fa579182015b82811115620005fa578251825591602001919060010190620005dd565b50620006089291506200060c565b5090565b6200062991905b8082111562000608576000815560010162000613565b90565b610dcd806200063c6000396000f3fe6080604052600436106100c25760003560e01c80636faa22a51161007f578063ae89a29e11610059578063ae89a29e1461036b578063b84dfbd214610380578063c45a015514610395578063f1739cae146103aa576100c2565b80636faa22a514610272578063958a41dd14610287578063983d273714610356576100c2565b8063025313a2146100cc5780632a0acc6a146100fd57806354fd4d50146101245780635a8b1a9f146101ae5780635c60da1b146102345780635c975abb14610249575b6100ca6103dd565b005b3480156100d857600080fd5b506100e16103ef565b604080516001600160a01b039092168252519081900360200190f35b34801561010957600080fd5b5061011261042c565b60408051918252519081900360200190f35b34801561013057600080fd5b5061013961043b565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561017357818101518382015260200161015b565b50505050905090810190601f1680156101a05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156101ba57600080fd5b506100ca600480360360408110156101d157600080fd5b8101906020810181356401000000008111156101ec57600080fd5b8201836020820111156101fe57600080fd5b8035906020019184600183028401116401000000008311171561022057600080fd5b9193509150356001600160a01b03166104f0565b34801561024057600080fd5b506100e1610564565b34801561025557600080fd5b5061025e61058f565b604080519115158252519081900360200190f35b34801561027e57600080fd5b506100e161059f565b6100ca6004803603606081101561029d57600080fd5b8101906020810181356401000000008111156102b857600080fd5b8201836020820111156102ca57600080fd5b803590602001918460018302840111640100000000831117156102ec57600080fd5b919390926001600160a01b038335169260408101906020013564010000000081111561031757600080fd5b82018360208201111561032957600080fd5b8035906020019184600183028401116401000000008311171561034b57600080fd5b5090925090506105ae565b34801561036257600080fd5b50610112610658565b34801561037757600080fd5b5061011261066a565b34801561038c57600080fd5b506100e1610670565b3480156103a157600080fd5b506100e161067f565b3480156103b657600080fd5b506100ca600480360360208110156103cd57600080fd5b50356001600160a01b031661068e565b6103ed6103e8610771565b610780565b565b60006103f96107a4565b6001600160a01b0316336001600160a01b031614156104215761041a6107a4565b9050610429565b6104296103dd565b90565b600160d91b6420a226a4a70281565b60606104456107a4565b6001600160a01b0316336001600160a01b03161415610421576004805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156104e45780601f106104b9576101008083540402835291602001916104e4565b820191906000526020600020905b8154815290600101906020018083116104c757829003601f168201915b50505050509050610429565b6104f86107a4565b6001600160a01b0316336001600160a01b031614156105575761055283838080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508592506107b3915050565b61055f565b61055f6103dd565b505050565b600061056e6107a4565b6001600160a01b0316336001600160a01b031614156104215761041a610771565b600354600160a01b900460ff1681565b6003546001600160a01b031681565b6105b66107a4565b6001600160a01b0316336001600160a01b031614156106495761064485858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f880181900481028201810190925286815288935091508690869081908401838280828437600092019190915250610aae92505050565b610651565b6106516103dd565b5050505050565b600160c11b6727a822a920aa27a90281565b60005481565b6002546001600160a01b031681565b6001546001600160a01b031681565b6106966107a4565b6001600160a01b0316336001600160a01b03161415610766576001600160a01b03811661070d5760408051600160e51b62461bcd02815260206004820152601860248201527f416464726573732073686f756c64206e6f742062652030780000000000000000604482015290519081900360640190fd5b7f5a3e66efaa1e445ebd894728a69d6959842ea1e97bd79b892797106e270efcd96107366107a4565b604080516001600160a01b03928316815291841660208301528051918290030190a161076181610ba7565b61076e565b61076e6103dd565b50565b6005546001600160a01b031690565b3660008037600080366000845af43d6000803e80801561079f573d6000f35b3d6000fd5b6006546001600160a01b031690565b6005546001600160a01b038281169116148015906107d957506001600160a01b03811615155b61081757604051600160e51b62461bcd028152600401808060200182810382526046815260200180610d216046913960600191505060405180910390fd5b61082081610c27565b61085e57604051600160e51b62461bcd02815260040180806020018281038252603b815260200180610d67603b913960400191505060405180910390fd5b60008251116108a157604051600160e51b62461bcd028152600401808060200182810382526022815260200180610cc66022913960400191505060405180910390fd5b816040516020018082805190602001908083835b602083106108d45780518252601f1990920191602091820191016108b5565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051602081830303815290604052805190602001206004604051602001808280546001816001161561010002031660029004801561096f5780601f1061094d57610100808354040283529182019161096f565b820191906000526020600020905b81548152906001019060200180831161095b575b50509150506040516020818303038152906040528051906020012014156109e05760408051600160e51b62461bcd02815260206004820152601d60248201527f4e65772076657273696f6e20657175616c7320746f2063757272656e74000000604482015290519081900360640190fd5b81516109f3906004906020850190610c2d565b50600580546001600160a01b0319166001600160a01b03831690811790915560408051602080825285518183015285517f8e05e0e35ff592971ca8b477d4285a33a61ded208d644042667b78693a472f5e938793928392918301919085019080838360005b83811015610a70578181015183820152602001610a58565b50505050905090810190601f168015610a9d5780820380516001836020036101000a031916815260200191505b509250505060405180910390a25050565b610ab883836107b3565b6000306001600160a01b031634836040518082805190602001908083835b60208310610af55780518252601f199092019160209182019101610ad6565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114610b57576040519150601f19603f3d011682016040523d82523d6000602084013e610b5c565b606091505b50508091505080610ba157604051600160e51b62461bcd028152600401808060200182810382526039815260200180610ce86039913960400191505060405180910390fd5b50505050565b6001600160a01b038116610c055760408051600160e51b62461bcd02815260206004820152601860248201527f416464726573732073686f756c64206e6f742062652030780000000000000000604482015290519081900360640190fd5b600680546001600160a01b0319166001600160a01b0392909216919091179055565b3b151590565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10610c6e57805160ff1916838001178555610c9b565b82800160010185558215610c9b579182015b82811115610c9b578251825591602001919060010190610c80565b50610ca7929150610cab565b5090565b61042991905b80821115610ca75760008155600101610cb156fe56657273696f6e2073686f756c64206e6f7420626520656d70747920737472696e674661696c20696e20657865637574696e67207468652066756e6374696f6e206f6620696d706c656d656e746174696f6e20636f6e74726163744f6c642061646472657373206973206e6f7420616c6c6f77656420616e6420696d706c656d656e746174696f6e20616464726573732073686f756c64206e6f7420626520307843616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e74726163742061646472657373a165627a7a7230582000fe58f7d1b721031cc1ce75379cbd525764e11e35fdb9974d50d71cc6925efd002956657273696f6e2073686f756c64206e6f7420626520656d70747920737472696e67496d706c656d656e746174696f6e20616464726573732073686f756c64206e6f742062652030784f6c642061646472657373206973206e6f7420616c6c6f77656420616e6420696d706c656d656e746174696f6e20616464726573732073686f756c64206e6f7420626520307843616e6e6f742073657420612070726f787920696d706c656d656e746174696f6e20746f2061206e6f6e2d636f6e74726163742061646472657373496e73756666696369656e7420616c6c6f77616e636520666f72206d6f64756c6520666565a165627a7a72305820be12e0c4ab525aee04b4fc043cf812e84c7ca8e1de337252d90ca8d5f6a214940029
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000efe0078e83cfbd370234f4bd44cba5d64e2ffd5c000000000000000000000000dfabf3e4793cd30affb47ab6fa4cf4eef26bbc270000000000000000000000000000000000000000000000000000000000000001
-----Decoded View---------------
Arg [0] : _setupCost (uint256): 0
Arg [1] : _logicContract (address): 0xeFe0078e83CFbd370234f4bD44cBa5D64e2ffD5C
Arg [2] : _polymathRegistry (address): 0xdFABF3e4793cD30aFFb47aB6fA4cF4eef26bBC27
Arg [3] : _isCostInPoly (bool): True
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [1] : 000000000000000000000000efe0078e83cfbd370234f4bd44cba5d64e2ffd5c
Arg [2] : 000000000000000000000000dfabf3e4793cd30affb47ab6fa4cf4eef26bbc27
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000001
Swarm Source
bzzr://be12e0c4ab525aee04b4fc043cf812e84c7ca8e1de337252d90ca8d5f6a21494
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
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.