ERC-721
Overview
Max Total Supply
0 AZP
Holders
0
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
0 AZPLoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
Ecliptic
Compiler Version
v0.4.24+commit.e67f0147
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2019-01-07 */ // the azimuth logic contract // https://azimuth.network pragma solidity 0.4.24; //////////////////////////////////////////////////////////////////////////////// // Imports //////////////////////////////////////////////////////////////////////////////// // OpenZeppelin's Ownable.sol /** * @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 public owner; event OwnershipRenounced(address indexed previousOwner); event OwnershipTransferred( address indexed previousOwner, address indexed newOwner ); /** * @dev The Ownable constructor sets the original `owner` of the contract to the sender * account. */ constructor() public { owner = msg.sender; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(msg.sender == owner); _; } /** * @dev Allows the current owner to relinquish control of the contract. * @notice Renouncing to ownership will leave the contract without an owner. * It will not be possible to call the functions with the `onlyOwner` * modifier anymore. */ function renounceOwnership() public onlyOwner { emit OwnershipRenounced(owner); 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; } } // Azimuth's SafeMath8.sol /** * @title SafeMath8 * @dev Math operations for uint8 with safety checks that throw on error */ library SafeMath8 { function mul(uint8 a, uint8 b) internal pure returns (uint8) { uint8 c = a * b; assert(a == 0 || c / a == b); return c; } function div(uint8 a, uint8 b) internal pure returns (uint8) { // assert(b > 0); // Solidity automatically throws when dividing by 0 uint8 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } function sub(uint8 a, uint8 b) internal pure returns (uint8) { assert(b <= a); return a - b; } function add(uint8 a, uint8 b) internal pure returns (uint8) { uint8 c = a + b; assert(c >= a); return c; } } // Azimuth's SafeMath16.sol /** * @title SafeMath16 * @dev Math operations for uint16 with safety checks that throw on error */ library SafeMath16 { function mul(uint16 a, uint16 b) internal pure returns (uint16) { uint16 c = a * b; assert(a == 0 || c / a == b); return c; } function div(uint16 a, uint16 b) internal pure returns (uint16) { // assert(b > 0); // Solidity automatically throws when dividing by 0 uint16 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } function sub(uint16 a, uint16 b) internal pure returns (uint16) { assert(b <= a); return a - b; } function add(uint16 a, uint16 b) internal pure returns (uint16) { uint16 c = a + b; assert(c >= a); return c; } } // OpenZeppelin's SafeMath.sol /** * @title SafeMath * @dev Math operations with safety checks that throw on error */ library SafeMath { /** * @dev Multiplies two numbers, throws on overflow. */ function mul(uint256 _a, uint256 _b) internal pure returns (uint256 c) { // Gas optimization: this is cheaper than asserting '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; } c = _a * _b; assert(c / _a == _b); return c; } /** * @dev Integer division of two numbers, truncating the quotient. */ function div(uint256 _a, uint256 _b) internal pure returns (uint256) { // assert(_b > 0); // Solidity automatically throws when dividing by 0 // uint256 c = _a / _b; // assert(_a == _b * c + _a % _b); // There is no case in which this doesn't hold return _a / _b; } /** * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend). */ function sub(uint256 _a, uint256 _b) internal pure returns (uint256) { assert(_b <= _a); return _a - _b; } /** * @dev Adds two numbers, throws on overflow. */ function add(uint256 _a, uint256 _b) internal pure returns (uint256 c) { c = _a + _b; assert(c >= _a); return c; } } // OpenZeppelin's ERC165.sol /** * @title ERC165 * @dev https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md */ interface ERC165 { /** * @notice Query if a contract implements an interface * @param _interfaceId The interface identifier, as specified in ERC-165 * @dev Interface identification is specified in ERC-165. This function * uses less than 30,000 gas. */ function supportsInterface(bytes4 _interfaceId) external view returns (bool); } // OpenZeppelin's SupportsInterfaceWithLookup.sol /** * @title SupportsInterfaceWithLookup * @author Matt Condon (@shrugs) * @dev Implements ERC165 using a lookup table. */ contract SupportsInterfaceWithLookup is ERC165 { bytes4 public constant InterfaceId_ERC165 = 0x01ffc9a7; /** * 0x01ffc9a7 === * bytes4(keccak256('supportsInterface(bytes4)')) */ /** * @dev a mapping of interface id to whether or not it's supported */ mapping(bytes4 => bool) internal supportedInterfaces; /** * @dev A contract implementing SupportsInterfaceWithLookup * implement ERC165 itself */ constructor() public { _registerInterface(InterfaceId_ERC165); } /** * @dev implement supportsInterface(bytes4) using a lookup table */ function supportsInterface(bytes4 _interfaceId) external view returns (bool) { return supportedInterfaces[_interfaceId]; } /** * @dev private method for registering an interface */ function _registerInterface(bytes4 _interfaceId) internal { require(_interfaceId != 0xffffffff); supportedInterfaces[_interfaceId] = true; } } // OpenZeppelin's ERC721Basic.sol /** * @title ERC721 Non-Fungible Token Standard basic interface * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md */ contract ERC721Basic is ERC165 { bytes4 internal constant InterfaceId_ERC721 = 0x80ac58cd; /* * 0x80ac58cd === * bytes4(keccak256('balanceOf(address)')) ^ * bytes4(keccak256('ownerOf(uint256)')) ^ * bytes4(keccak256('approve(address,uint256)')) ^ * bytes4(keccak256('getApproved(uint256)')) ^ * bytes4(keccak256('setApprovalForAll(address,bool)')) ^ * bytes4(keccak256('isApprovedForAll(address,address)')) ^ * bytes4(keccak256('transferFrom(address,address,uint256)')) ^ * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) ^ * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) */ bytes4 internal constant InterfaceId_ERC721Exists = 0x4f558e79; /* * 0x4f558e79 === * bytes4(keccak256('exists(uint256)')) */ bytes4 internal constant InterfaceId_ERC721Enumerable = 0x780e9d63; /** * 0x780e9d63 === * bytes4(keccak256('totalSupply()')) ^ * bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) ^ * bytes4(keccak256('tokenByIndex(uint256)')) */ bytes4 internal constant InterfaceId_ERC721Metadata = 0x5b5e139f; /** * 0x5b5e139f === * bytes4(keccak256('name()')) ^ * bytes4(keccak256('symbol()')) ^ * bytes4(keccak256('tokenURI(uint256)')) */ event Transfer( address indexed _from, address indexed _to, uint256 indexed _tokenId ); event Approval( address indexed _owner, address indexed _approved, uint256 indexed _tokenId ); event ApprovalForAll( address indexed _owner, address indexed _operator, bool _approved ); function balanceOf(address _owner) public view returns (uint256 _balance); function ownerOf(uint256 _tokenId) public view returns (address _owner); function exists(uint256 _tokenId) public view returns (bool _exists); function approve(address _to, uint256 _tokenId) public; function getApproved(uint256 _tokenId) public view returns (address _operator); function setApprovalForAll(address _operator, bool _approved) public; function isApprovedForAll(address _owner, address _operator) public view returns (bool); function transferFrom(address _from, address _to, uint256 _tokenId) public; function safeTransferFrom(address _from, address _to, uint256 _tokenId) public; function safeTransferFrom( address _from, address _to, uint256 _tokenId, bytes _data ) public; } // OpenZeppelin's ERC721.sol /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md */ contract ERC721Enumerable is ERC721Basic { function totalSupply() public view returns (uint256); function tokenOfOwnerByIndex( address _owner, uint256 _index ) public view returns (uint256 _tokenId); function tokenByIndex(uint256 _index) public view returns (uint256); } /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md */ contract ERC721Metadata is ERC721Basic { function name() external view returns (string _name); function symbol() external view returns (string _symbol); function tokenURI(uint256 _tokenId) public view returns (string); } /** * @title ERC-721 Non-Fungible Token Standard, full implementation interface * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md */ contract ERC721 is ERC721Basic, ERC721Enumerable, ERC721Metadata { } // OpenZeppelin's ERC721Receiver.sol /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ contract ERC721Receiver { /** * @dev Magic value to be returned upon successful reception of an NFT * Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`, * which can be also obtained as `ERC721Receiver(0).onERC721Received.selector` */ bytes4 internal constant ERC721_RECEIVED = 0x150b7a02; /** * @notice Handle the receipt of an NFT * @dev The ERC721 smart contract calls this function on the recipient * after a `safetransfer`. This function MAY throw to revert and reject the * transfer. Return of other than the magic value MUST result in the * transaction being reverted. * Note: the contract address is always the message sender. * @param _operator The address which called `safeTransferFrom` function * @param _from The address which previously owned the token * @param _tokenId The NFT identifier which is being transferred * @param _data Additional data with no specified format * @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` */ function onERC721Received( address _operator, address _from, uint256 _tokenId, bytes _data ) public returns(bytes4); } // OpenZeppelin's AddressUtils.sol /** * Utility library of inline functions on addresses */ library AddressUtils { /** * 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 _addr address to check * @return whether the target address is a contract */ function isContract(address _addr) 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. // solium-disable-next-line security/no-inline-assembly assembly { size := extcodesize(_addr) } return size > 0; } } // Azimuth's Azimuth.sol // Azimuth: point state data contract // // This contract is used for storing all data related to Azimuth points // and their ownership. Consider this contract the Azimuth ledger. // // It also contains permissions data, which ties in to ERC721 // functionality. Operators of an address are allowed to transfer // ownership of all points owned by their associated address // (ERC721's approveAll()). A transfer proxy is allowed to transfer // ownership of a single point (ERC721's approve()). // Separate from ERC721 are managers, assigned per point. They are // allowed to perform "low-impact" operations on the owner's points, // like configuring public keys and making escape requests. // // Since data stores are difficult to upgrade, this contract contains // as little actual business logic as possible. Instead, the data stored // herein can only be modified by this contract's owner, which can be // changed and is thus upgradable/replaceable. // // This contract will be owned by the Ecliptic contract. // contract Azimuth is Ownable { // // Events // // OwnerChanged: :point is now owned by :owner // event OwnerChanged(uint32 indexed point, address indexed owner); // Activated: :point is now active // event Activated(uint32 indexed point); // Spawned: :prefix has spawned :child // event Spawned(uint32 indexed prefix, uint32 indexed child); // EscapeRequested: :point has requested a new :sponsor // event EscapeRequested(uint32 indexed point, uint32 indexed sponsor); // EscapeCanceled: :point's :sponsor request was canceled or rejected // event EscapeCanceled(uint32 indexed point, uint32 indexed sponsor); // EscapeAccepted: :point confirmed with a new :sponsor // event EscapeAccepted(uint32 indexed point, uint32 indexed sponsor); // LostSponsor: :point's :sponsor is now refusing it service // event LostSponsor(uint32 indexed point, uint32 indexed sponsor); // ChangedKeys: :point has new network public keys // event ChangedKeys( uint32 indexed point, bytes32 encryptionKey, bytes32 authenticationKey, uint32 cryptoSuiteVersion, uint32 keyRevisionNumber ); // BrokeContinuity: :point has a new continuity number, :number // event BrokeContinuity(uint32 indexed point, uint32 number); // ChangedSpawnProxy: :spawnProxy can now spawn using :point // event ChangedSpawnProxy(uint32 indexed point, address indexed spawnProxy); // ChangedTransferProxy: :transferProxy can now transfer ownership of :point // event ChangedTransferProxy( uint32 indexed point, address indexed transferProxy ); // ChangedManagementProxy: :managementProxy can now manage :point // event ChangedManagementProxy( uint32 indexed point, address indexed managementProxy ); // ChangedVotingProxy: :votingProxy can now vote using :point // event ChangedVotingProxy(uint32 indexed point, address indexed votingProxy); // ChangedDns: dnsDomains have been updated // event ChangedDns(string primary, string secondary, string tertiary); // // Structures // // Size: kinds of points registered on-chain // // NOTE: the order matters, because of Solidity enum numbering // enum Size { Galaxy, // = 0 Star, // = 1 Planet // = 2 } // Point: state of a point // // While the ordering of the struct members is semantically chaotic, // they are ordered to tightly pack them into Ethereum's 32-byte storage // slots, which reduces gas costs for some function calls. // The comment ticks indicate assumed slot boundaries. // struct Point { // encryptionKey: (curve25519) encryption public key, or 0 for none // bytes32 encryptionKey; // // authenticationKey: (ed25519) authentication public key, or 0 for none // bytes32 authenticationKey; // // spawned: for stars and galaxies, all :active children // uint32[] spawned; // // hasSponsor: true if the sponsor still supports the point // bool hasSponsor; // active: whether point can be linked // // false: point belongs to prefix, cannot be configured or linked // true: point no longer belongs to prefix, can be configured and linked // bool active; // escapeRequested: true if the point has requested to change sponsors // bool escapeRequested; // sponsor: the point that supports this one on the network, or, // if :hasSponsor is false, the last point that supported it. // (by default, the point's half-width prefix) // uint32 sponsor; // escapeRequestedTo: if :escapeRequested is true, new sponsor requested // uint32 escapeRequestedTo; // cryptoSuiteVersion: version of the crypto suite used for the pubkeys // uint32 cryptoSuiteVersion; // keyRevisionNumber: incremented every time the public keys change // uint32 keyRevisionNumber; // continuityNumber: incremented to indicate network-side state loss // uint32 continuityNumber; } // Deed: permissions for a point // struct Deed { // owner: address that owns this point // address owner; // managementProxy: 0, or another address with the right to perform // low-impact, managerial operations on this point // address managementProxy; // spawnProxy: 0, or another address with the right to spawn children // of this point // address spawnProxy; // votingProxy: 0, or another address with the right to vote as this point // address votingProxy; // transferProxy: 0, or another address with the right to transfer // ownership of this point // address transferProxy; } // // General state // // points: per point, general network-relevant point state // mapping(uint32 => Point) public points; // rights: per point, on-chain ownership and permissions // mapping(uint32 => Deed) public rights; // operators: per owner, per address, has the right to transfer ownership // of all the owner's points (ERC721) // mapping(address => mapping(address => bool)) public operators; // dnsDomains: base domains for contacting galaxies // // dnsDomains[0] is primary, the others are used as fallbacks // string[3] public dnsDomains; // // Lookups // // sponsoring: per point, the points they are sponsoring // mapping(uint32 => uint32[]) public sponsoring; // sponsoringIndexes: per point, per point, (index + 1) in // the sponsoring array // mapping(uint32 => mapping(uint32 => uint256)) public sponsoringIndexes; // escapeRequests: per point, the points they have open escape requests from // mapping(uint32 => uint32[]) public escapeRequests; // escapeRequestsIndexes: per point, per point, (index + 1) in // the escapeRequests array // mapping(uint32 => mapping(uint32 => uint256)) public escapeRequestsIndexes; // pointsOwnedBy: per address, the points they own // mapping(address => uint32[]) public pointsOwnedBy; // pointOwnerIndexes: per owner, per point, (index + 1) in // the pointsOwnedBy array // // We delete owners by moving the last entry in the array to the // newly emptied slot, which is (n - 1) where n is the value of // pointOwnerIndexes[owner][point]. // mapping(address => mapping(uint32 => uint256)) public pointOwnerIndexes; // managerFor: per address, the points they are the management proxy for // mapping(address => uint32[]) public managerFor; // managerForIndexes: per address, per point, (index + 1) in // the managerFor array // mapping(address => mapping(uint32 => uint256)) public managerForIndexes; // spawningFor: per address, the points they can spawn with // mapping(address => uint32[]) public spawningFor; // spawningForIndexes: per address, per point, (index + 1) in // the spawningFor array // mapping(address => mapping(uint32 => uint256)) public spawningForIndexes; // votingFor: per address, the points they can vote with // mapping(address => uint32[]) public votingFor; // votingForIndexes: per address, per point, (index + 1) in // the votingFor array // mapping(address => mapping(uint32 => uint256)) public votingForIndexes; // transferringFor: per address, the points they can transfer // mapping(address => uint32[]) public transferringFor; // transferringForIndexes: per address, per point, (index + 1) in // the transferringFor array // mapping(address => mapping(uint32 => uint256)) public transferringForIndexes; // // Logic // // constructor(): configure default dns domains // constructor() public { setDnsDomains("example.com", "example.com", "example.com"); } // setDnsDomains(): set the base domains used for contacting galaxies // // Note: since a string is really just a byte[], and Solidity can't // work with two-dimensional arrays yet, we pass in the three // domains as individual strings. // function setDnsDomains(string _primary, string _secondary, string _tertiary) onlyOwner public { dnsDomains[0] = _primary; dnsDomains[1] = _secondary; dnsDomains[2] = _tertiary; emit ChangedDns(_primary, _secondary, _tertiary); } // // Point reading // // isActive(): return true if _point is active // function isActive(uint32 _point) view external returns (bool equals) { return points[_point].active; } // getKeys(): returns the public keys and their details, as currently // registered for _point // function getKeys(uint32 _point) view external returns (bytes32 crypt, bytes32 auth, uint32 suite, uint32 revision) { Point storage point = points[_point]; return (point.encryptionKey, point.authenticationKey, point.cryptoSuiteVersion, point.keyRevisionNumber); } // getKeyRevisionNumber(): gets the revision number of _point's current // public keys // function getKeyRevisionNumber(uint32 _point) view external returns (uint32 revision) { return points[_point].keyRevisionNumber; } // hasBeenLinked(): returns true if the point has ever been assigned keys // function hasBeenLinked(uint32 _point) view external returns (bool result) { return ( points[_point].keyRevisionNumber > 0 ); } // isLive(): returns true if _point currently has keys properly configured // function isLive(uint32 _point) view external returns (bool result) { Point storage point = points[_point]; return ( point.encryptionKey != 0 && point.authenticationKey != 0 && point.cryptoSuiteVersion != 0 ); } // getContinuityNumber(): returns _point's current continuity number // function getContinuityNumber(uint32 _point) view external returns (uint32 continuityNumber) { return points[_point].continuityNumber; } // getSpawnCount(): return the number of children spawned by _point // function getSpawnCount(uint32 _point) view external returns (uint32 spawnCount) { uint256 len = points[_point].spawned.length; assert(len < 2**32); return uint32(len); } // getSpawned(): return array of points created under _point // // Note: only useful for clients, as Solidity does not currently // support returning dynamic arrays. // function getSpawned(uint32 _point) view external returns (uint32[] spawned) { return points[_point].spawned; } // hasSponsor(): returns true if _point's sponsor is providing it service // function hasSponsor(uint32 _point) view external returns (bool has) { return points[_point].hasSponsor; } // getSponsor(): returns _point's current (or most recent) sponsor // function getSponsor(uint32 _point) view external returns (uint32 sponsor) { return points[_point].sponsor; } // isSponsor(): returns true if _sponsor is currently providing service // to _point // function isSponsor(uint32 _point, uint32 _sponsor) view external returns (bool result) { Point storage point = points[_point]; return ( point.hasSponsor && (point.sponsor == _sponsor) ); } // getSponsoringCount(): returns the number of points _sponsor is // providing service to // function getSponsoringCount(uint32 _sponsor) view external returns (uint256 count) { return sponsoring[_sponsor].length; } // getSponsoring(): returns a list of points _sponsor is providing // service to // // Note: only useful for clients, as Solidity does not currently // support returning dynamic arrays. // function getSponsoring(uint32 _sponsor) view external returns (uint32[] sponsees) { return sponsoring[_sponsor]; } // escaping // isEscaping(): returns true if _point has an outstanding escape request // function isEscaping(uint32 _point) view external returns (bool escaping) { return points[_point].escapeRequested; } // getEscapeRequest(): returns _point's current escape request // // the returned escape request is only valid as long as isEscaping() // returns true // function getEscapeRequest(uint32 _point) view external returns (uint32 escape) { return points[_point].escapeRequestedTo; } // isRequestingEscapeTo(): returns true if _point has an outstanding // escape request targetting _sponsor // function isRequestingEscapeTo(uint32 _point, uint32 _sponsor) view public returns (bool equals) { Point storage point = points[_point]; return (point.escapeRequested && (point.escapeRequestedTo == _sponsor)); } // getEscapeRequestsCount(): returns the number of points _sponsor // is providing service to // function getEscapeRequestsCount(uint32 _sponsor) view external returns (uint256 count) { return escapeRequests[_sponsor].length; } // getEscapeRequests(): get the points _sponsor has received escape // requests from // // Note: only useful for clients, as Solidity does not currently // support returning dynamic arrays. // function getEscapeRequests(uint32 _sponsor) view external returns (uint32[] requests) { return escapeRequests[_sponsor]; } // // Point writing // // activatePoint(): activate a point, register it as spawned by its prefix // function activatePoint(uint32 _point) onlyOwner external { // make a point active, setting its sponsor to its prefix // Point storage point = points[_point]; require(!point.active); point.active = true; registerSponsor(_point, true, getPrefix(_point)); emit Activated(_point); } // setKeys(): set network public keys of _point to _encryptionKey and // _authenticationKey, with the specified _cryptoSuiteVersion // function setKeys(uint32 _point, bytes32 _encryptionKey, bytes32 _authenticationKey, uint32 _cryptoSuiteVersion) onlyOwner external { Point storage point = points[_point]; if ( point.encryptionKey == _encryptionKey && point.authenticationKey == _authenticationKey && point.cryptoSuiteVersion == _cryptoSuiteVersion ) { return; } point.encryptionKey = _encryptionKey; point.authenticationKey = _authenticationKey; point.cryptoSuiteVersion = _cryptoSuiteVersion; point.keyRevisionNumber++; emit ChangedKeys(_point, _encryptionKey, _authenticationKey, _cryptoSuiteVersion, point.keyRevisionNumber); } // incrementContinuityNumber(): break continuity for _point // function incrementContinuityNumber(uint32 _point) onlyOwner external { Point storage point = points[_point]; point.continuityNumber++; emit BrokeContinuity(_point, point.continuityNumber); } // registerSpawn(): add a point to its prefix's list of spawned points // function registerSpawned(uint32 _point) onlyOwner external { // if a point is its own prefix (a galaxy) then don't register it // uint32 prefix = getPrefix(_point); if (prefix == _point) { return; } // register a new spawned point for the prefix // points[prefix].spawned.push(_point); emit Spawned(prefix, _point); } // loseSponsor(): indicates that _point's sponsor is no longer providing // it service // function loseSponsor(uint32 _point) onlyOwner external { Point storage point = points[_point]; if (!point.hasSponsor) { return; } registerSponsor(_point, false, point.sponsor); emit LostSponsor(_point, point.sponsor); } // setEscapeRequest(): for _point, start an escape request to _sponsor // function setEscapeRequest(uint32 _point, uint32 _sponsor) onlyOwner external { if (isRequestingEscapeTo(_point, _sponsor)) { return; } registerEscapeRequest(_point, true, _sponsor); emit EscapeRequested(_point, _sponsor); } // cancelEscape(): for _point, stop the current escape request, if any // function cancelEscape(uint32 _point) onlyOwner external { Point storage point = points[_point]; if (!point.escapeRequested) { return; } uint32 request = point.escapeRequestedTo; registerEscapeRequest(_point, false, 0); emit EscapeCanceled(_point, request); } // doEscape(): perform the requested escape // function doEscape(uint32 _point) onlyOwner external { Point storage point = points[_point]; require(point.escapeRequested); registerSponsor(_point, true, point.escapeRequestedTo); registerEscapeRequest(_point, false, 0); emit EscapeAccepted(_point, point.sponsor); } // // Point utils // // getPrefix(): compute prefix ("parent") of _point // function getPrefix(uint32 _point) pure public returns (uint16 prefix) { if (_point < 0x10000) { return uint16(_point % 0x100); } return uint16(_point % 0x10000); } // getPointSize(): return the size of _point // function getPointSize(uint32 _point) external pure returns (Size _size) { if (_point < 0x100) return Size.Galaxy; if (_point < 0x10000) return Size.Star; return Size.Planet; } // internal use // registerSponsor(): set the sponsorship state of _point and update the // reverse lookup for sponsors // function registerSponsor(uint32 _point, bool _hasSponsor, uint32 _sponsor) internal { Point storage point = points[_point]; bool had = point.hasSponsor; uint32 prev = point.sponsor; // if we didn't have a sponsor, and won't get one, // or if we get the sponsor we already have, // nothing will change, so jump out early. // if ( (!had && !_hasSponsor) || (had && _hasSponsor && prev == _sponsor) ) { return; } // if the point used to have a different sponsor, do some gymnastics // to keep the reverse lookup gapless. delete the point from the old // sponsor's list, then fill that gap with the list tail. // if (had) { // i: current index in previous sponsor's list of sponsored points // uint256 i = sponsoringIndexes[prev][_point]; // we store index + 1, because 0 is the solidity default value // assert(i > 0); i--; // copy the last item in the list into the now-unused slot, // making sure to update its :sponsoringIndexes reference // uint32[] storage prevSponsoring = sponsoring[prev]; uint256 last = prevSponsoring.length - 1; uint32 moved = prevSponsoring[last]; prevSponsoring[i] = moved; sponsoringIndexes[prev][moved] = i + 1; // delete the last item // delete(prevSponsoring[last]); prevSponsoring.length = last; sponsoringIndexes[prev][_point] = 0; } if (_hasSponsor) { uint32[] storage newSponsoring = sponsoring[_sponsor]; newSponsoring.push(_point); sponsoringIndexes[_sponsor][_point] = newSponsoring.length; } point.sponsor = _sponsor; point.hasSponsor = _hasSponsor; } // registerEscapeRequest(): set the escape state of _point and update the // reverse lookup for sponsors // function registerEscapeRequest( uint32 _point, bool _isEscaping, uint32 _sponsor ) internal { Point storage point = points[_point]; bool was = point.escapeRequested; uint32 prev = point.escapeRequestedTo; // if we weren't escaping, and won't be, // or if we were escaping, and the new target is the same, // nothing will change, so jump out early. // if ( (!was && !_isEscaping) || (was && _isEscaping && prev == _sponsor) ) { return; } // if the point used to have a different request, do some gymnastics // to keep the reverse lookup gapless. delete the point from the old // sponsor's list, then fill that gap with the list tail. // if (was) { // i: current index in previous sponsor's list of sponsored points // uint256 i = escapeRequestsIndexes[prev][_point]; // we store index + 1, because 0 is the solidity default value // assert(i > 0); i--; // copy the last item in the list into the now-unused slot, // making sure to update its :escapeRequestsIndexes reference // uint32[] storage prevRequests = escapeRequests[prev]; uint256 last = prevRequests.length - 1; uint32 moved = prevRequests[last]; prevRequests[i] = moved; escapeRequestsIndexes[prev][moved] = i + 1; // delete the last item // delete(prevRequests[last]); prevRequests.length = last; escapeRequestsIndexes[prev][_point] = 0; } if (_isEscaping) { uint32[] storage newRequests = escapeRequests[_sponsor]; newRequests.push(_point); escapeRequestsIndexes[_sponsor][_point] = newRequests.length; } point.escapeRequestedTo = _sponsor; point.escapeRequested = _isEscaping; } // // Deed reading // // owner // getOwner(): return owner of _point // function getOwner(uint32 _point) view external returns (address owner) { return rights[_point].owner; } // isOwner(): true if _point is owned by _address // function isOwner(uint32 _point, address _address) view external returns (bool result) { return (rights[_point].owner == _address); } // getOwnedPointCount(): return length of array of points that _whose owns // function getOwnedPointCount(address _whose) view external returns (uint256 count) { return pointsOwnedBy[_whose].length; } // getOwnedPoints(): return array of points that _whose owns // // Note: only useful for clients, as Solidity does not currently // support returning dynamic arrays. // function getOwnedPoints(address _whose) view external returns (uint32[] ownedPoints) { return pointsOwnedBy[_whose]; } // getOwnedPointAtIndex(): get point at _index from array of points that // _whose owns // function getOwnedPointAtIndex(address _whose, uint256 _index) view external returns (uint32 point) { uint32[] storage owned = pointsOwnedBy[_whose]; require(_index < owned.length); return owned[_index]; } // management proxy // getManagementProxy(): returns _point's current management proxy // function getManagementProxy(uint32 _point) view external returns (address manager) { return rights[_point].managementProxy; } // isManagementProxy(): returns true if _proxy is _point's management proxy // function isManagementProxy(uint32 _point, address _proxy) view external returns (bool result) { return (rights[_point].managementProxy == _proxy); } // canManage(): true if _who is the owner or manager of _point // function canManage(uint32 _point, address _who) view external returns (bool result) { Deed storage deed = rights[_point]; return ( (0x0 != _who) && ( (_who == deed.owner) || (_who == deed.managementProxy) ) ); } // getManagerForCount(): returns the amount of points _proxy can manage // function getManagerForCount(address _proxy) view external returns (uint256 count) { return managerFor[_proxy].length; } // getManagerFor(): returns the points _proxy can manage // // Note: only useful for clients, as Solidity does not currently // support returning dynamic arrays. // function getManagerFor(address _proxy) view external returns (uint32[] mfor) { return managerFor[_proxy]; } // spawn proxy // getSpawnProxy(): returns _point's current spawn proxy // function getSpawnProxy(uint32 _point) view external returns (address spawnProxy) { return rights[_point].spawnProxy; } // isSpawnProxy(): returns true if _proxy is _point's spawn proxy // function isSpawnProxy(uint32 _point, address _proxy) view external returns (bool result) { return (rights[_point].spawnProxy == _proxy); } // canSpawnAs(): true if _who is the owner or spawn proxy of _point // function canSpawnAs(uint32 _point, address _who) view external returns (bool result) { Deed storage deed = rights[_point]; return ( (0x0 != _who) && ( (_who == deed.owner) || (_who == deed.spawnProxy) ) ); } // getSpawningForCount(): returns the amount of points _proxy // can spawn with // function getSpawningForCount(address _proxy) view external returns (uint256 count) { return spawningFor[_proxy].length; } // getSpawningFor(): get the points _proxy can spawn with // // Note: only useful for clients, as Solidity does not currently // support returning dynamic arrays. // function getSpawningFor(address _proxy) view external returns (uint32[] sfor) { return spawningFor[_proxy]; } // voting proxy // getVotingProxy(): returns _point's current voting proxy // function getVotingProxy(uint32 _point) view external returns (address voter) { return rights[_point].votingProxy; } // isVotingProxy(): returns true if _proxy is _point's voting proxy // function isVotingProxy(uint32 _point, address _proxy) view external returns (bool result) { return (rights[_point].votingProxy == _proxy); } // canVoteAs(): true if _who is the owner of _point, // or the voting proxy of _point's owner // function canVoteAs(uint32 _point, address _who) view external returns (bool result) { Deed storage deed = rights[_point]; return ( (0x0 != _who) && ( (_who == deed.owner) || (_who == deed.votingProxy) ) ); } // getVotingForCount(): returns the amount of points _proxy can vote as // function getVotingForCount(address _proxy) view external returns (uint256 count) { return votingFor[_proxy].length; } // getVotingFor(): returns the points _proxy can vote as // // Note: only useful for clients, as Solidity does not currently // support returning dynamic arrays. // function getVotingFor(address _proxy) view external returns (uint32[] vfor) { return votingFor[_proxy]; } // transfer proxy // getTransferProxy(): returns _point's current transfer proxy // function getTransferProxy(uint32 _point) view external returns (address transferProxy) { return rights[_point].transferProxy; } // isTransferProxy(): returns true if _proxy is _point's transfer proxy // function isTransferProxy(uint32 _point, address _proxy) view external returns (bool result) { return (rights[_point].transferProxy == _proxy); } // canTransfer(): true if _who is the owner or transfer proxy of _point, // or is an operator for _point's current owner // function canTransfer(uint32 _point, address _who) view external returns (bool result) { Deed storage deed = rights[_point]; return ( (0x0 != _who) && ( (_who == deed.owner) || (_who == deed.transferProxy) || operators[deed.owner][_who] ) ); } // getTransferringForCount(): returns the amount of points _proxy // can transfer // function getTransferringForCount(address _proxy) view external returns (uint256 count) { return transferringFor[_proxy].length; } // getTransferringFor(): get the points _proxy can transfer // // Note: only useful for clients, as Solidity does not currently // support returning dynamic arrays. // function getTransferringFor(address _proxy) view external returns (uint32[] tfor) { return transferringFor[_proxy]; } // isOperator(): returns true if _operator is allowed to transfer // ownership of _owner's points // function isOperator(address _owner, address _operator) view external returns (bool result) { return operators[_owner][_operator]; } // // Deed writing // // setOwner(): set owner of _point to _owner // // Note: setOwner() only implements the minimal data storage // logic for a transfer; the full transfer is implemented in // Ecliptic. // // Note: _owner must not be the zero address. // function setOwner(uint32 _point, address _owner) onlyOwner external { // prevent burning of points by making zero the owner // require(0x0 != _owner); // prev: previous owner, if any // address prev = rights[_point].owner; if (prev == _owner) { return; } // if the point used to have a different owner, do some gymnastics to // keep the list of owned points gapless. delete this point from the // list, then fill that gap with the list tail. // if (0x0 != prev) { // i: current index in previous owner's list of owned points // uint256 i = pointOwnerIndexes[prev][_point]; // we store index + 1, because 0 is the solidity default value // assert(i > 0); i--; // copy the last item in the list into the now-unused slot, // making sure to update its :pointOwnerIndexes reference // uint32[] storage owner = pointsOwnedBy[prev]; uint256 last = owner.length - 1; uint32 moved = owner[last]; owner[i] = moved; pointOwnerIndexes[prev][moved] = i + 1; // delete the last item // delete(owner[last]); owner.length = last; pointOwnerIndexes[prev][_point] = 0; } // update the owner list and the owner's index list // rights[_point].owner = _owner; pointsOwnedBy[_owner].push(_point); pointOwnerIndexes[_owner][_point] = pointsOwnedBy[_owner].length; emit OwnerChanged(_point, _owner); } // setManagementProxy(): makes _proxy _point's management proxy // function setManagementProxy(uint32 _point, address _proxy) onlyOwner external { Deed storage deed = rights[_point]; address prev = deed.managementProxy; if (prev == _proxy) { return; } // if the point used to have a different manager, do some gymnastics // to keep the reverse lookup gapless. delete the point from the // old manager's list, then fill that gap with the list tail. // if (0x0 != prev) { // i: current index in previous manager's list of managed points // uint256 i = managerForIndexes[prev][_point]; // we store index + 1, because 0 is the solidity default value // assert(i > 0); i--; // copy the last item in the list into the now-unused slot, // making sure to update its :managerForIndexes reference // uint32[] storage prevMfor = managerFor[prev]; uint256 last = prevMfor.length - 1; uint32 moved = prevMfor[last]; prevMfor[i] = moved; managerForIndexes[prev][moved] = i + 1; // delete the last item // delete(prevMfor[last]); prevMfor.length = last; managerForIndexes[prev][_point] = 0; } if (0x0 != _proxy) { uint32[] storage mfor = managerFor[_proxy]; mfor.push(_point); managerForIndexes[_proxy][_point] = mfor.length; } deed.managementProxy = _proxy; emit ChangedManagementProxy(_point, _proxy); } // setSpawnProxy(): makes _proxy _point's spawn proxy // function setSpawnProxy(uint32 _point, address _proxy) onlyOwner external { Deed storage deed = rights[_point]; address prev = deed.spawnProxy; if (prev == _proxy) { return; } // if the point used to have a different spawn proxy, do some // gymnastics to keep the reverse lookup gapless. delete the point // from the old proxy's list, then fill that gap with the list tail. // if (0x0 != prev) { // i: current index in previous proxy's list of spawning points // uint256 i = spawningForIndexes[prev][_point]; // we store index + 1, because 0 is the solidity default value // assert(i > 0); i--; // copy the last item in the list into the now-unused slot, // making sure to update its :spawningForIndexes reference // uint32[] storage prevSfor = spawningFor[prev]; uint256 last = prevSfor.length - 1; uint32 moved = prevSfor[last]; prevSfor[i] = moved; spawningForIndexes[prev][moved] = i + 1; // delete the last item // delete(prevSfor[last]); prevSfor.length = last; spawningForIndexes[prev][_point] = 0; } if (0x0 != _proxy) { uint32[] storage sfor = spawningFor[_proxy]; sfor.push(_point); spawningForIndexes[_proxy][_point] = sfor.length; } deed.spawnProxy = _proxy; emit ChangedSpawnProxy(_point, _proxy); } // setVotingProxy(): makes _proxy _point's voting proxy // function setVotingProxy(uint32 _point, address _proxy) onlyOwner external { Deed storage deed = rights[_point]; address prev = deed.votingProxy; if (prev == _proxy) { return; } // if the point used to have a different voter, do some gymnastics // to keep the reverse lookup gapless. delete the point from the // old voter's list, then fill that gap with the list tail. // if (0x0 != prev) { // i: current index in previous voter's list of points it was // voting for // uint256 i = votingForIndexes[prev][_point]; // we store index + 1, because 0 is the solidity default value // assert(i > 0); i--; // copy the last item in the list into the now-unused slot, // making sure to update its :votingForIndexes reference // uint32[] storage prevVfor = votingFor[prev]; uint256 last = prevVfor.length - 1; uint32 moved = prevVfor[last]; prevVfor[i] = moved; votingForIndexes[prev][moved] = i + 1; // delete the last item // delete(prevVfor[last]); prevVfor.length = last; votingForIndexes[prev][_point] = 0; } if (0x0 != _proxy) { uint32[] storage vfor = votingFor[_proxy]; vfor.push(_point); votingForIndexes[_proxy][_point] = vfor.length; } deed.votingProxy = _proxy; emit ChangedVotingProxy(_point, _proxy); } // setManagementProxy(): makes _proxy _point's transfer proxy // function setTransferProxy(uint32 _point, address _proxy) onlyOwner external { Deed storage deed = rights[_point]; address prev = deed.transferProxy; if (prev == _proxy) { return; } // if the point used to have a different transfer proxy, do some // gymnastics to keep the reverse lookup gapless. delete the point // from the old proxy's list, then fill that gap with the list tail. // if (0x0 != prev) { // i: current index in previous proxy's list of transferable points // uint256 i = transferringForIndexes[prev][_point]; // we store index + 1, because 0 is the solidity default value // assert(i > 0); i--; // copy the last item in the list into the now-unused slot, // making sure to update its :transferringForIndexes reference // uint32[] storage prevTfor = transferringFor[prev]; uint256 last = prevTfor.length - 1; uint32 moved = prevTfor[last]; prevTfor[i] = moved; transferringForIndexes[prev][moved] = i + 1; // delete the last item // delete(prevTfor[last]); prevTfor.length = last; transferringForIndexes[prev][_point] = 0; } if (0x0 != _proxy) { uint32[] storage tfor = transferringFor[_proxy]; tfor.push(_point); transferringForIndexes[_proxy][_point] = tfor.length; } deed.transferProxy = _proxy; emit ChangedTransferProxy(_point, _proxy); } // setOperator(): dis/allow _operator to transfer ownership of all points // owned by _owner // // operators are part of the ERC721 standard // function setOperator(address _owner, address _operator, bool _approved) onlyOwner external { operators[_owner][_operator] = _approved; } } // Azimuth's ReadsAzimuth.sol // ReadsAzimuth: referring to and testing against the Azimuth // data contract // // To avoid needless repetition, this contract provides common // checks and operations using the Azimuth contract. // contract ReadsAzimuth { // azimuth: points data storage contract. // Azimuth public azimuth; // constructor(): set the Azimuth data contract's address // constructor(Azimuth _azimuth) public { azimuth = _azimuth; } // activePointOwner(): require that :msg.sender is the owner of _point, // and that _point is active // modifier activePointOwner(uint32 _point) { require( azimuth.isOwner(_point, msg.sender) && azimuth.isActive(_point) ); _; } // activePointManager(): require that :msg.sender can manage _point, // and that _point is active // modifier activePointManager(uint32 _point) { require( azimuth.canManage(_point, msg.sender) && azimuth.isActive(_point) ); _; } } // Azimuth's Polls.sol // Polls: proposals & votes data contract // // This contract is used for storing all data related to the proposals // of the senate (galaxy owners) and their votes on those proposals. // It keeps track of votes and uses them to calculate whether a majority // is in favor of a proposal. // // Every galaxy can only vote on a proposal exactly once. Votes cannot // be changed. If a proposal fails to achieve majority within its // duration, it can be restarted after its cooldown period has passed. // // The requirements for a proposal to achieve majority are as follows: // - At least 1/4 of the currently active voters (rounded down) must have // voted in favor of the proposal, // - More than half of the votes cast must be in favor of the proposal, // and this can no longer change, either because // - the poll duration has passed, or // - not enough voters remain to take away the in-favor majority. // As soon as these conditions are met, no further interaction with // the proposal is possible. Achieving majority is permanent. // // Since data stores are difficult to upgrade, all of the logic unrelated // to the voting itself (that is, determining who is eligible to vote) // is expected to be implemented by this contract's owner. // // This contract will be owned by the Ecliptic contract. // contract Polls is Ownable { using SafeMath for uint256; using SafeMath16 for uint16; using SafeMath8 for uint8; // UpgradePollStarted: a poll on :proposal has opened // event UpgradePollStarted(address proposal); // DocumentPollStarted: a poll on :proposal has opened // event DocumentPollStarted(bytes32 proposal); // UpgradeMajority: :proposal has achieved majority // event UpgradeMajority(address proposal); // DocumentMajority: :proposal has achieved majority // event DocumentMajority(bytes32 proposal); // Poll: full poll state // struct Poll { // start: the timestamp at which the poll was started // uint256 start; // voted: per galaxy, whether they have voted on this poll // bool[256] voted; // yesVotes: amount of votes in favor of the proposal // uint16 yesVotes; // noVotes: amount of votes against the proposal // uint16 noVotes; // duration: amount of time during which the poll can be voted on // uint256 duration; // cooldown: amount of time before the (non-majority) poll can be reopened // uint256 cooldown; } // pollDuration: duration set for new polls. see also Poll.duration above // uint256 public pollDuration; // pollCooldown: cooldown set for new polls. see also Poll.cooldown above // uint256 public pollCooldown; // totalVoters: amount of active galaxies // uint16 public totalVoters; // upgradeProposals: list of all upgrades ever proposed // // this allows clients to discover the existence of polls. // from there, they can do liveness checks on the polls themselves. // address[] public upgradeProposals; // upgradePolls: per address, poll held to determine if that address // will become the new ecliptic // mapping(address => Poll) public upgradePolls; // upgradeHasAchievedMajority: per address, whether that address // has ever achieved majority // // If we did not store this, we would have to look at old poll data // to see whether or not a proposal has ever achieved majority. // Since the outcome of a poll is calculated based on :totalVoters, // which may not be consistent across time, we need to store outcomes // explicitly instead of re-calculating them. This allows us to always // tell with certainty whether or not a majority was achieved, // regardless of the current :totalVoters. // mapping(address => bool) public upgradeHasAchievedMajority; // documentProposals: list of all documents ever proposed // // this allows clients to discover the existence of polls. // from there, they can do liveness checks on the polls themselves. // bytes32[] public documentProposals; // documentPolls: per hash, poll held to determine if the corresponding // document is accepted by the galactic senate // mapping(bytes32 => Poll) public documentPolls; // documentHasAchievedMajority: per hash, whether that hash has ever // achieved majority // // the note for upgradeHasAchievedMajority above applies here as well // mapping(bytes32 => bool) public documentHasAchievedMajority; // documentMajorities: all hashes that have achieved majority // bytes32[] public documentMajorities; // constructor(): initial contract configuration // constructor(uint256 _pollDuration, uint256 _pollCooldown) public { reconfigure(_pollDuration, _pollCooldown); } // reconfigure(): change poll duration and cooldown // function reconfigure(uint256 _pollDuration, uint256 _pollCooldown) public onlyOwner { require( (5 days <= _pollDuration) && (_pollDuration <= 90 days) && (5 days <= _pollCooldown) && (_pollCooldown <= 90 days) ); pollDuration = _pollDuration; pollCooldown = _pollCooldown; } // incrementTotalVoters(): increase the amount of registered voters // function incrementTotalVoters() external onlyOwner { require(totalVoters < 256); totalVoters = totalVoters.add(1); } // getAllUpgradeProposals(): return array of all upgrade proposals ever made // // Note: only useful for clients, as Solidity does not currently // support returning dynamic arrays. // function getUpgradeProposals() external view returns (address[] proposals) { return upgradeProposals; } // getUpgradeProposalCount(): get the number of unique proposed upgrades // function getUpgradeProposalCount() external view returns (uint256 count) { return upgradeProposals.length; } // getAllDocumentProposals(): return array of all upgrade proposals ever made // // Note: only useful for clients, as Solidity does not currently // support returning dynamic arrays. // function getDocumentProposals() external view returns (bytes32[] proposals) { return documentProposals; } // getDocumentProposalCount(): get the number of unique proposed upgrades // function getDocumentProposalCount() external view returns (uint256 count) { return documentProposals.length; } // getDocumentMajorities(): return array of all document majorities // // Note: only useful for clients, as Solidity does not currently // support returning dynamic arrays. // function getDocumentMajorities() external view returns (bytes32[] majorities) { return documentMajorities; } // hasVotedOnUpgradePoll(): returns true if _galaxy has voted // on the _proposal // function hasVotedOnUpgradePoll(uint8 _galaxy, address _proposal) external view returns (bool result) { return upgradePolls[_proposal].voted[_galaxy]; } // hasVotedOnDocumentPoll(): returns true if _galaxy has voted // on the _proposal // function hasVotedOnDocumentPoll(uint8 _galaxy, bytes32 _proposal) external view returns (bool result) { return documentPolls[_proposal].voted[_galaxy]; } // startUpgradePoll(): open a poll on making _proposal the new ecliptic // function startUpgradePoll(address _proposal) external onlyOwner { // _proposal must not have achieved majority before // require(!upgradeHasAchievedMajority[_proposal]); Poll storage poll = upgradePolls[_proposal]; // if the proposal is being made for the first time, register it. // if (0 == poll.start) { upgradeProposals.push(_proposal); } startPoll(poll); emit UpgradePollStarted(_proposal); } // startDocumentPoll(): open a poll on accepting the document // whose hash is _proposal // function startDocumentPoll(bytes32 _proposal) external onlyOwner { // _proposal must not have achieved majority before // require(!documentHasAchievedMajority[_proposal]); Poll storage poll = documentPolls[_proposal]; // if the proposal is being made for the first time, register it. // if (0 == poll.start) { documentProposals.push(_proposal); } startPoll(poll); emit DocumentPollStarted(_proposal); } // startPoll(): open a new poll, or re-open an old one // function startPoll(Poll storage _poll) internal { // check that the poll has cooled down enough to be started again // // for completely new polls, the values used will be zero // require( block.timestamp > ( _poll.start.add( _poll.duration.add( _poll.cooldown )) ) ); // set started poll state // _poll.start = block.timestamp; delete _poll.voted; _poll.yesVotes = 0; _poll.noVotes = 0; _poll.duration = pollDuration; _poll.cooldown = pollCooldown; } // castUpgradeVote(): as galaxy _as, cast a vote on the _proposal // // _vote is true when in favor of the proposal, false otherwise // function castUpgradeVote(uint8 _as, address _proposal, bool _vote) external onlyOwner returns (bool majority) { Poll storage poll = upgradePolls[_proposal]; processVote(poll, _as, _vote); return updateUpgradePoll(_proposal); } // castDocumentVote(): as galaxy _as, cast a vote on the _proposal // // _vote is true when in favor of the proposal, false otherwise // function castDocumentVote(uint8 _as, bytes32 _proposal, bool _vote) external onlyOwner returns (bool majority) { Poll storage poll = documentPolls[_proposal]; processVote(poll, _as, _vote); return updateDocumentPoll(_proposal); } // processVote(): record a vote from _as on the _poll // function processVote(Poll storage _poll, uint8 _as, bool _vote) internal { // assist symbolic execution tools // assert(block.timestamp >= _poll.start); require( // may only vote once // !_poll.voted[_as] && // // may only vote when the poll is open // (block.timestamp < _poll.start.add(_poll.duration)) ); // update poll state to account for the new vote // _poll.voted[_as] = true; if (_vote) { _poll.yesVotes = _poll.yesVotes.add(1); } else { _poll.noVotes = _poll.noVotes.add(1); } } // updateUpgradePoll(): check whether the _proposal has achieved // majority, updating state, sending an event, // and returning true if it has // function updateUpgradePoll(address _proposal) public onlyOwner returns (bool majority) { // _proposal must not have achieved majority before // require(!upgradeHasAchievedMajority[_proposal]); // check for majority in the poll // Poll storage poll = upgradePolls[_proposal]; majority = checkPollMajority(poll); // if majority was achieved, update the state and send an event // if (majority) { upgradeHasAchievedMajority[_proposal] = true; emit UpgradeMajority(_proposal); } return majority; } // updateDocumentPoll(): check whether the _proposal has achieved majority, // updating the state and sending an event if it has // // this can be called by anyone, because the ecliptic does not // need to be aware of the result // function updateDocumentPoll(bytes32 _proposal) public returns (bool majority) { // _proposal must not have achieved majority before // require(!documentHasAchievedMajority[_proposal]); // check for majority in the poll // Poll storage poll = documentPolls[_proposal]; majority = checkPollMajority(poll); // if majority was achieved, update state and send an event // if (majority) { documentHasAchievedMajority[_proposal] = true; documentMajorities.push(_proposal); emit DocumentMajority(_proposal); } return majority; } // checkPollMajority(): returns true if the majority is in favor of // the subject of the poll // function checkPollMajority(Poll _poll) internal view returns (bool majority) { return ( // poll must have at least the minimum required yes-votes // (_poll.yesVotes >= (totalVoters / 4)) && // // and have a majority... // (_poll.yesVotes > _poll.noVotes) && // // ...that is indisputable // ( // either because the poll has ended // (block.timestamp > _poll.start.add(_poll.duration)) || // // or there are more yes votes than there can be no votes // ( _poll.yesVotes > totalVoters.sub(_poll.yesVotes) ) ) ); } } // Azimuth's Claims.sol // Claims: simple identity management // // This contract allows points to document claims about their owner. // Most commonly, these are about identity, with a claim's protocol // defining the context or platform of the claim, and its dossier // containing proof of its validity. // Points are limited to a maximum of 16 claims. // // For existing claims, the dossier can be updated, or the claim can // be removed entirely. It is recommended to remove any claims associated // with a point when it is about to be transferred to a new owner. // For convenience, the owner of the Azimuth contract (the Ecliptic) // is allowed to clear claims for any point, allowing it to do this for // you on-transfer. // contract Claims is ReadsAzimuth { // ClaimAdded: a claim was added by :by // event ClaimAdded( uint32 indexed by, string _protocol, string _claim, bytes _dossier ); // ClaimRemoved: a claim was removed by :by // event ClaimRemoved(uint32 indexed by, string _protocol, string _claim); // maxClaims: the amount of claims that can be registered per point // uint8 constant maxClaims = 16; // Claim: claim details // struct Claim { // protocol: context of the claim // string protocol; // claim: the claim itself // string claim; // dossier: data relating to the claim, as proof // bytes dossier; } // per point, list of claims // mapping(uint32 => Claim[maxClaims]) public claims; // constructor(): register the azimuth contract. // constructor(Azimuth _azimuth) ReadsAzimuth(_azimuth) public { // } // addClaim(): register a claim as _point // function addClaim(uint32 _point, string _protocol, string _claim, bytes _dossier) external activePointManager(_point) { // cur: index + 1 of the claim if it already exists, 0 otherwise // uint8 cur = findClaim(_point, _protocol, _claim); // if the claim doesn't yet exist, store it in state // if (cur == 0) { // if there are no empty slots left, this throws // uint8 empty = findEmptySlot(_point); claims[_point][empty] = Claim(_protocol, _claim, _dossier); } // // if the claim has been made before, update the version in state // else { claims[_point][cur-1] = Claim(_protocol, _claim, _dossier); } emit ClaimAdded(_point, _protocol, _claim, _dossier); } // removeClaim(): unregister a claim as _point // function removeClaim(uint32 _point, string _protocol, string _claim) external activePointManager(_point) { // i: current index + 1 in _point's list of claims // uint256 i = findClaim(_point, _protocol, _claim); // we store index + 1, because 0 is the eth default value // can only delete an existing claim // require(i > 0); i--; // clear out the claim // delete claims[_point][i]; emit ClaimRemoved(_point, _protocol, _claim); } // clearClaims(): unregister all of _point's claims // // can also be called by the ecliptic during point transfer // function clearClaims(uint32 _point) external { // both point owner and ecliptic may do this // // We do not necessarily need to check for _point's active flag here, // since inactive points cannot have claims set. Doing the check // anyway would make this function slightly harder to think about due // to its relation to Ecliptic's transferPoint(). // require( azimuth.canManage(_point, msg.sender) || ( msg.sender == azimuth.owner() ) ); Claim[maxClaims] storage currClaims = claims[_point]; // clear out all claims // for (uint8 i = 0; i < maxClaims; i++) { delete currClaims[i]; } } // findClaim(): find the index of the specified claim // // returns 0 if not found, index + 1 otherwise // function findClaim(uint32 _whose, string _protocol, string _claim) public view returns (uint8 index) { // we use hashes of the string because solidity can't do string // comparison yet // bytes32 protocolHash = keccak256(bytes(_protocol)); bytes32 claimHash = keccak256(bytes(_claim)); Claim[maxClaims] storage theirClaims = claims[_whose]; for (uint8 i = 0; i < maxClaims; i++) { Claim storage thisClaim = theirClaims[i]; if ( ( protocolHash == keccak256(bytes(thisClaim.protocol)) ) && ( claimHash == keccak256(bytes(thisClaim.claim)) ) ) { return i+1; } } return 0; } // findEmptySlot(): find the index of the first empty claim slot // // returns the index of the slot, throws if there are no empty slots // function findEmptySlot(uint32 _whose) internal view returns (uint8 index) { Claim[maxClaims] storage theirClaims = claims[_whose]; for (uint8 i = 0; i < maxClaims; i++) { Claim storage thisClaim = theirClaims[i]; if ( (0 == bytes(thisClaim.protocol).length) && (0 == bytes(thisClaim.claim).length) ) { return i; } } revert(); } } // Azimuth's EclipticBase.sol // EclipticBase: upgradable ecliptic // // This contract implements the upgrade logic for the Ecliptic. // Newer versions of the Ecliptic are expected to provide at least // the onUpgrade() function. If they don't, upgrading to them will // fail. // // Note that even though this contract doesn't specify any required // interface members aside from upgrade() and onUpgrade(), contracts // and clients may still rely on the presence of certain functions // provided by the Ecliptic proper. Keep this in mind when writing // new versions of it. // contract EclipticBase is Ownable, ReadsAzimuth { // Upgraded: _to is the new canonical Ecliptic // event Upgraded(address to); // polls: senate voting contract // Polls public polls; // previousEcliptic: address of the previous ecliptic this // instance expects to upgrade from, stored and // checked for to prevent unexpected upgrade paths // address public previousEcliptic; constructor( address _previous, Azimuth _azimuth, Polls _polls ) ReadsAzimuth(_azimuth) internal { previousEcliptic = _previous; polls = _polls; } // onUpgrade(): called by previous ecliptic when upgrading // // in future ecliptics, this might perform more logic than // just simple checks and verifications. // when overriding this, make sure to call this original as well. // function onUpgrade() external { // make sure this is the expected upgrade path, // and that we have gotten the ownership we require // require( msg.sender == previousEcliptic && this == azimuth.owner() && this == polls.owner() ); } // upgrade(): transfer ownership of the ecliptic data to the new // ecliptic contract, notify it, then self-destruct. // // Note: any eth that have somehow ended up in this contract // are also sent to the new ecliptic. // function upgrade(EclipticBase _new) internal { // transfer ownership of the data contracts // azimuth.transferOwnership(_new); polls.transferOwnership(_new); // trigger upgrade logic on the target contract // _new.onUpgrade(); // emit event and destroy this contract // emit Upgraded(_new); selfdestruct(_new); } } //////////////////////////////////////////////////////////////////////////////// // Ecliptic //////////////////////////////////////////////////////////////////////////////// // Ecliptic: logic for interacting with the Azimuth ledger // // This contract is the point of entry for all operations on the Azimuth // ledger as stored in the Azimuth data contract. The functions herein // are responsible for performing all necessary business logic. // Examples of such logic include verifying permissions of the caller // and ensuring a requested change is actually valid. // Point owners can always operate on their own points. Ethereum addresses // can also perform specific operations if they've been given the // appropriate permissions. (For example, managers for general management, // spawn proxies for spawning child points, etc.) // // This contract uses external contracts (Azimuth, Polls) for data storage // so that it itself can easily be replaced in case its logic needs to // be changed. In other words, it can be upgraded. It does this by passing // ownership of the data contracts to a new Ecliptic contract. // // Because of this, it is advised for clients to not store this contract's // address directly, but rather ask the Azimuth contract for its owner // attribute to ensure transactions get sent to the latest Ecliptic. // Alternatively, the ENS name ecliptic.eth will resolve to the latest // Ecliptic as well. // // Upgrading happens based on polls held by the senate (galaxy owners). // Through this contract, the senate can submit proposals, opening polls // for the senate to cast votes on. These proposals can be either hashes // of documents or addresses of new Ecliptics. // If an ecliptic proposal gains majority, this contract will transfer // ownership of the data storage contracts to that address, so that it may // operate on the data they contain. This contract will selfdestruct at // the end of the upgrade process. // // This contract implements the ERC721 interface for non-fungible tokens, // allowing points to be managed using generic clients that support the // standard. It also implements ERC165 to allow this to be discovered. // contract Ecliptic is EclipticBase, SupportsInterfaceWithLookup, ERC721Metadata { using SafeMath for uint256; using AddressUtils for address; // Transfer: This emits when ownership of any NFT changes by any mechanism. // This event emits when NFTs are created (`from` == 0) and // destroyed (`to` == 0). At the time of any transfer, the // approved address for that NFT (if any) is reset to none. // event Transfer(address indexed _from, address indexed _to, uint256 _tokenId); // Approval: This emits when the approved address for an NFT is changed or // reaffirmed. The zero address indicates there is no approved // address. When a Transfer event emits, this also indicates that // the approved address for that NFT (if any) is reset to none. // event Approval(address indexed _owner, address indexed _approved, uint256 _tokenId); // ApprovalForAll: This emits when an operator is enabled or disabled for an // owner. The operator can manage all NFTs of the owner. // event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); // erc721Received: equal to: // bytes4(keccak256("onERC721Received(address,address,uint256,bytes)")) // which can be also obtained as: // ERC721Receiver(0).onERC721Received.selector` bytes4 constant erc721Received = 0x150b7a02; // claims: contract reference, for clearing claims on-transfer // Claims public claims; // constructor(): set data contract addresses and signal interface support // // Note: during first deploy, ownership of these data contracts must // be manually transferred to this contract. // constructor(address _previous, Azimuth _azimuth, Polls _polls, Claims _claims) EclipticBase(_previous, _azimuth, _polls) public { claims = _claims; // register supported interfaces for ERC165 // _registerInterface(0x80ac58cd); // ERC721 _registerInterface(0x5b5e139f); // ERC721Metadata _registerInterface(0x7f5828d0); // ERC173 (ownership) } // // ERC721 interface // // balanceOf(): get the amount of points owned by _owner // function balanceOf(address _owner) public view returns (uint256 balance) { require(0x0 != _owner); return azimuth.getOwnedPointCount(_owner); } // ownerOf(): get the current owner of point _tokenId // function ownerOf(uint256 _tokenId) public view validPointId(_tokenId) returns (address owner) { uint32 id = uint32(_tokenId); // this will throw if the owner is the zero address, // active points always have a valid owner. // require(azimuth.isActive(id)); return azimuth.getOwner(id); } // exists(): returns true if point _tokenId is active // function exists(uint256 _tokenId) public view returns (bool doesExist) { return ( (_tokenId < 0x100000000) && azimuth.isActive(uint32(_tokenId)) ); } // safeTransferFrom(): transfer point _tokenId from _from to _to // function safeTransferFrom(address _from, address _to, uint256 _tokenId) public { // transfer with empty data // safeTransferFrom(_from, _to, _tokenId, ""); } // safeTransferFrom(): transfer point _tokenId from _from to _to, // and call recipient if it's a contract // function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes _data) public { // perform raw transfer // transferFrom(_from, _to, _tokenId); // do the callback last to avoid re-entrancy // if (_to.isContract()) { bytes4 retval = ERC721Receiver(_to) .onERC721Received(msg.sender, _from, _tokenId, _data); // // standard return idiom to confirm contract semantics // require(retval == erc721Received); } } // transferFrom(): transfer point _tokenId from _from to _to, // WITHOUT notifying recipient contract // function transferFrom(address _from, address _to, uint256 _tokenId) public validPointId(_tokenId) { uint32 id = uint32(_tokenId); require(azimuth.isOwner(id, _from)); // the ERC721 operator/approved address (if any) is // accounted for in transferPoint() // transferPoint(id, _to, true); } // approve(): allow _approved to transfer ownership of point // _tokenId // function approve(address _approved, uint256 _tokenId) public validPointId(_tokenId) { setTransferProxy(uint32(_tokenId), _approved); } // setApprovalForAll(): allow or disallow _operator to // transfer ownership of ALL points // owned by :msg.sender // function setApprovalForAll(address _operator, bool _approved) public { require(0x0 != _operator); azimuth.setOperator(msg.sender, _operator, _approved); emit ApprovalForAll(msg.sender, _operator, _approved); } // getApproved(): get the approved address for point _tokenId // function getApproved(uint256 _tokenId) public view validPointId(_tokenId) returns (address approved) { //NOTE redundant, transfer proxy cannot be set for // inactive points // require(azimuth.isActive(uint32(_tokenId))); return azimuth.getTransferProxy(uint32(_tokenId)); } // isApprovedForAll(): returns true if _operator is an // operator for _owner // function isApprovedForAll(address _owner, address _operator) public view returns (bool result) { return azimuth.isOperator(_owner, _operator); } // // ERC721Metadata interface // // name(): returns the name of a collection of points // function name() external view returns (string) { return "Azimuth Points"; } // symbol(): returns an abbreviates name for points // function symbol() external view returns (string) { return "AZP"; } // tokenURI(): returns a URL to an ERC-721 standard JSON file // function tokenURI(uint256 _tokenId) public view validPointId(_tokenId) returns (string _tokenURI) { _tokenURI = "https://azimuth.network/erc721/0000000000.json"; bytes memory _tokenURIBytes = bytes(_tokenURI); _tokenURIBytes[31] = byte(48+(_tokenId / 1000000000) % 10); _tokenURIBytes[32] = byte(48+(_tokenId / 100000000) % 10); _tokenURIBytes[33] = byte(48+(_tokenId / 10000000) % 10); _tokenURIBytes[34] = byte(48+(_tokenId / 1000000) % 10); _tokenURIBytes[35] = byte(48+(_tokenId / 100000) % 10); _tokenURIBytes[36] = byte(48+(_tokenId / 10000) % 10); _tokenURIBytes[37] = byte(48+(_tokenId / 1000) % 10); _tokenURIBytes[38] = byte(48+(_tokenId / 100) % 10); _tokenURIBytes[39] = byte(48+(_tokenId / 10) % 10); _tokenURIBytes[40] = byte(48+(_tokenId / 1) % 10); } // // Points interface // // configureKeys(): configure _point with network public keys // _encryptionKey, _authenticationKey, // and corresponding _cryptoSuiteVersion, // incrementing the point's continuity number if needed // function configureKeys(uint32 _point, bytes32 _encryptionKey, bytes32 _authenticationKey, uint32 _cryptoSuiteVersion, bool _discontinuous) external activePointManager(_point) { if (_discontinuous) { azimuth.incrementContinuityNumber(_point); } azimuth.setKeys(_point, _encryptionKey, _authenticationKey, _cryptoSuiteVersion); } // spawn(): spawn _point, then either give, or allow _target to take, // ownership of _point // // if _target is the :msg.sender, _targets owns the _point right away. // otherwise, _target becomes the transfer proxy of _point. // // Requirements: // - _point must not be active // - _point must not be a planet with a galaxy prefix // - _point's prefix must be linked and under its spawn limit // - :msg.sender must be either the owner of _point's prefix, // or an authorized spawn proxy for it // function spawn(uint32 _point, address _target) external { // only currently unowned (and thus also inactive) points can be spawned // require(azimuth.isOwner(_point, 0x0)); // prefix: half-width prefix of _point // uint16 prefix = azimuth.getPrefix(_point); // only allow spawning of points of the size directly below the prefix // // this is possible because of how the address space works, // but supporting it introduces complexity through broken assumptions. // // example: // 0x0000.0000 - galaxy zero // 0x0000.0100 - the first star of galaxy zero // 0x0001.0100 - the first planet of the first star // 0x0001.0000 - the first planet of galaxy zero // require( (uint8(azimuth.getPointSize(prefix)) + 1) == uint8(azimuth.getPointSize(_point)) ); // prefix point must be linked and able to spawn // require( (azimuth.hasBeenLinked(prefix)) && ( azimuth.getSpawnCount(prefix) < getSpawnLimit(prefix, block.timestamp) ) ); // the owner of a prefix can always spawn its children; // other addresses need explicit permission (the role // of "spawnProxy" in the Azimuth contract) // require( azimuth.canSpawnAs(prefix, msg.sender) ); // if the caller is spawning the point to themselves, // assume it knows what it's doing and resolve right away // if (msg.sender == _target) { doSpawn(_point, _target, true, 0x0); } // // when sending to a "foreign" address, enforce a withdraw pattern // making the _point prefix's owner the _point owner in the mean time // else { doSpawn(_point, _target, false, azimuth.getOwner(prefix)); } } // doSpawn(): actual spawning logic, used in spawn(). creates _point, // making the _target its owner if _direct, or making the // _holder the owner and the _target the transfer proxy // if not _direct. // function doSpawn( uint32 _point, address _target, bool _direct, address _holder ) internal { // register the spawn for _point's prefix, incrementing spawn count // azimuth.registerSpawned(_point); // if the spawn is _direct, assume _target knows what they're doing // and resolve right away // if (_direct) { // make the point active and set its new owner // azimuth.activatePoint(_point); azimuth.setOwner(_point, _target); emit Transfer(0x0, _target, uint256(_point)); } // // when spawning indirectly, enforce a withdraw pattern by approving // the _target for transfer of the _point instead. // we make the _holder the owner of this _point in the mean time, // so that it may cancel the transfer (un-approve) if _target flakes. // we don't make _point active yet, because it still doesn't really // belong to anyone. // else { // have _holder hold on to the _point while _target gets to transfer // ownership of it // azimuth.setOwner(_point, _holder); azimuth.setTransferProxy(_point, _target); emit Transfer(0x0, _holder, uint256(_point)); emit Approval(_holder, _target, uint256(_point)); } } // transferPoint(): transfer _point to _target, clearing all permissions // data and keys if _reset is true // // Note: the _reset flag is useful when transferring the point to // a recipient who doesn't trust the previous owner. // // Requirements: // - :msg.sender must be either _point's current owner, authorized // to transfer _point, or authorized to transfer the current // owner's points (as in ERC721's operator) // - _target must not be the zero address // function transferPoint(uint32 _point, address _target, bool _reset) public { // transfer is legitimate if the caller is the current owner, or // an operator for the current owner, or the _point's transfer proxy // require(azimuth.canTransfer(_point, msg.sender)); // if the point wasn't active yet, that means transferring it // is part of the "spawn" flow, so we need to activate it // if ( !azimuth.isActive(_point) ) { azimuth.activatePoint(_point); } // if the owner would actually change, change it // // the only time this deliberately wouldn't be the case is when a // prefix owner wants to activate a spawned but untransferred child. // if ( !azimuth.isOwner(_point, _target) ) { // remember the previous owner, to be included in the Transfer event // address old = azimuth.getOwner(_point); azimuth.setOwner(_point, _target); // according to ERC721, the approved address (here, transfer proxy) // gets cleared during every Transfer event // azimuth.setTransferProxy(_point, 0); emit Transfer(old, _target, uint256(_point)); } // reset sensitive data // used when transferring the point to a new owner // if ( _reset ) { // clear the network public keys and break continuity, // but only if the point has already been linked // if ( azimuth.hasBeenLinked(_point) ) { azimuth.incrementContinuityNumber(_point); azimuth.setKeys(_point, 0, 0, 0); } // clear management proxy // azimuth.setManagementProxy(_point, 0); // clear voting proxy // azimuth.setVotingProxy(_point, 0); // clear transfer proxy // // in most cases this is done above, during the ownership transfer, // but we might not hit that and still be expected to reset the // transfer proxy. // doing it a second time is a no-op in Azimuth. // azimuth.setTransferProxy(_point, 0); // clear spawning proxy // azimuth.setSpawnProxy(_point, 0); // clear claims // claims.clearClaims(_point); } } // escape(): request escape as _point to _sponsor // // if an escape request is already active, this overwrites // the existing request // // Requirements: // - :msg.sender must be the owner or manager of _point, // - _point must be able to escape to _sponsor as per to canEscapeTo() // function escape(uint32 _point, uint32 _sponsor) external activePointManager(_point) { require(canEscapeTo(_point, _sponsor)); azimuth.setEscapeRequest(_point, _sponsor); } // cancelEscape(): cancel the currently set escape for _point // function cancelEscape(uint32 _point) external activePointManager(_point) { azimuth.cancelEscape(_point); } // adopt(): as the relevant sponsor, accept the _point // // Requirements: // - :msg.sender must be the owner or management proxy // of _point's requested sponsor // function adopt(uint32 _point) external { require( azimuth.isEscaping(_point) && azimuth.canManage( azimuth.getEscapeRequest(_point), msg.sender ) ); // _sponsor becomes _point's sponsor // its escape request is reset to "not escaping" // azimuth.doEscape(_point); } // reject(): as the relevant sponsor, deny the _point's request // // Requirements: // - :msg.sender must be the owner or management proxy // of _point's requested sponsor // function reject(uint32 _point) external { require( azimuth.isEscaping(_point) && azimuth.canManage( azimuth.getEscapeRequest(_point), msg.sender ) ); // reset the _point's escape request to "not escaping" // azimuth.cancelEscape(_point); } // detach(): as the _sponsor, stop sponsoring the _point // // Requirements: // - :msg.sender must be the owner or management proxy // of _point's current sponsor // function detach(uint32 _point) external { require( azimuth.hasSponsor(_point) && azimuth.canManage(azimuth.getSponsor(_point), msg.sender) ); // signal that its sponsor no longer supports _point // azimuth.loseSponsor(_point); } // // Point rules // // getSpawnLimit(): returns the total number of children the _point // is allowed to spawn at _time. // function getSpawnLimit(uint32 _point, uint256 _time) public view returns (uint32 limit) { Azimuth.Size size = azimuth.getPointSize(_point); if ( size == Azimuth.Size.Galaxy ) { return 255; } else if ( size == Azimuth.Size.Star ) { // in 2019, stars may spawn at most 1024 planets. this limit doubles // for every subsequent year. // // Note: 1546300800 corresponds to 2019-01-01 // uint256 yearsSince2019 = (_time - 1546300800) / 365 days; if (yearsSince2019 < 6) { limit = uint32( 1024 * (2 ** yearsSince2019) ); } else { limit = 65535; } return limit; } else // size == Azimuth.Size.Planet { // planets can create moons, but moons aren't on the chain // return 0; } } // canEscapeTo(): true if _point could try to escape to _sponsor // function canEscapeTo(uint32 _point, uint32 _sponsor) public view returns (bool canEscape) { // can't escape to a sponsor that hasn't been linked // if ( !azimuth.hasBeenLinked(_sponsor) ) return false; // Can only escape to a point one size higher than ourselves, // except in the special case where the escaping point hasn't // been linked yet -- in that case we may escape to points of // the same size, to support lightweight invitation chains. // // The use case for lightweight invitations is that a planet // owner should be able to invite their friends onto an // Azimuth network in a two-party transaction, without a new // star relationship. // The lightweight invitation process works by escaping your // own active (but never linked) point to one of your own // points, then transferring the point to your friend. // // These planets can, in turn, sponsor other unlinked planets, // so the "planet sponsorship chain" can grow to arbitrary // length. Most users, especially deep down the chain, will // want to improve their performance by switching to direct // star sponsors eventually. // Azimuth.Size pointSize = azimuth.getPointSize(_point); Azimuth.Size sponsorSize = azimuth.getPointSize(_sponsor); return ( // normal hierarchical escape structure // ( (uint8(sponsorSize) + 1) == uint8(pointSize) ) || // // special peer escape // ( (sponsorSize == pointSize) && // // peer escape is only for points that haven't been linked // yet, because it's only for lightweight invitation chains // !azimuth.hasBeenLinked(_point) ) ); } // // Permission management // // setManagementProxy(): configure the management proxy for _point // // The management proxy may perform "reversible" operations on // behalf of the owner. This includes public key configuration and // operations relating to sponsorship. // function setManagementProxy(uint32 _point, address _manager) external activePointOwner(_point) { azimuth.setManagementProxy(_point, _manager); } // setSpawnProxy(): give _spawnProxy the right to spawn points // with the prefix _prefix // function setSpawnProxy(uint16 _prefix, address _spawnProxy) external activePointOwner(_prefix) { azimuth.setSpawnProxy(_prefix, _spawnProxy); } // setVotingProxy(): configure the voting proxy for _galaxy // // the voting proxy is allowed to start polls and cast votes // on the point's behalf. // function setVotingProxy(uint8 _galaxy, address _voter) external activePointOwner(_galaxy) { azimuth.setVotingProxy(_galaxy, _voter); } // setTransferProxy(): give _transferProxy the right to transfer _point // // Requirements: // - :msg.sender must be either _point's current owner, // or be an operator for the current owner // function setTransferProxy(uint32 _point, address _transferProxy) public { // owner: owner of _point // address owner = azimuth.getOwner(_point); // caller must be :owner, or an operator designated by the owner. // require((owner == msg.sender) || azimuth.isOperator(owner, msg.sender)); // set transfer proxy field in Azimuth contract // azimuth.setTransferProxy(_point, _transferProxy); // emit Approval event // emit Approval(owner, _transferProxy, uint256(_point)); } // // Poll actions // // startUpgradePoll(): as _galaxy, start a poll for the ecliptic // upgrade _proposal // // Requirements: // - :msg.sender must be the owner or voting proxy of _galaxy, // - the _proposal must expect to be upgraded from this specific // contract, as indicated by its previousEcliptic attribute // function startUpgradePoll(uint8 _galaxy, EclipticBase _proposal) external activePointVoter(_galaxy) { // ensure that the upgrade target expects this contract as the source // require(_proposal.previousEcliptic() == address(this)); polls.startUpgradePoll(_proposal); } // startDocumentPoll(): as _galaxy, start a poll for the _proposal // // the _proposal argument is the keccak-256 hash of any arbitrary // document or string of text // function startDocumentPoll(uint8 _galaxy, bytes32 _proposal) external activePointVoter(_galaxy) { polls.startDocumentPoll(_proposal); } // castUpgradeVote(): as _galaxy, cast a _vote on the ecliptic // upgrade _proposal // // _vote is true when in favor of the proposal, false otherwise // // If this vote results in a majority for the _proposal, it will // be upgraded to immediately. // function castUpgradeVote(uint8 _galaxy, EclipticBase _proposal, bool _vote) external activePointVoter(_galaxy) { // majority: true if the vote resulted in a majority, false otherwise // bool majority = polls.castUpgradeVote(_galaxy, _proposal, _vote); // if a majority is in favor of the upgrade, it happens as defined // in the ecliptic base contract // if (majority) { upgrade(_proposal); } } // castDocumentVote(): as _galaxy, cast a _vote on the _proposal // // _vote is true when in favor of the proposal, false otherwise // function castDocumentVote(uint8 _galaxy, bytes32 _proposal, bool _vote) external activePointVoter(_galaxy) { polls.castDocumentVote(_galaxy, _proposal, _vote); } // updateUpgradePoll(): check whether the _proposal has achieved // majority, upgrading to it if it has // function updateUpgradePoll(EclipticBase _proposal) external { // majority: true if the poll ended in a majority, false otherwise // bool majority = polls.updateUpgradePoll(_proposal); // if a majority is in favor of the upgrade, it happens as defined // in the ecliptic base contract // if (majority) { upgrade(_proposal); } } // updateDocumentPoll(): check whether the _proposal has achieved majority // // Note: the polls contract publicly exposes the function this calls, // but we offer it in the ecliptic interface as a convenience // function updateDocumentPoll(bytes32 _proposal) external { polls.updateDocumentPoll(_proposal); } // // Contract owner operations // // createGalaxy(): grant _target ownership of the _galaxy and register // it for voting // function createGalaxy(uint8 _galaxy, address _target) external onlyOwner { // only currently unowned (and thus also inactive) galaxies can be // created, and only to non-zero addresses // require( azimuth.isOwner(_galaxy, 0x0) && 0x0 != _target ); // new galaxy means a new registered voter // polls.incrementTotalVoters(); // if the caller is sending the galaxy to themselves, // assume it knows what it's doing and resolve right away // if (msg.sender == _target) { doSpawn(_galaxy, _target, true, 0x0); } // // when sending to a "foreign" address, enforce a withdraw pattern, // making the caller the owner in the mean time // else { doSpawn(_galaxy, _target, false, msg.sender); } } function setDnsDomains(string _primary, string _secondary, string _tertiary) external onlyOwner { azimuth.setDnsDomains(_primary, _secondary, _tertiary); } // // Function modifiers for this contract // // validPointId(): require that _id is a valid point // modifier validPointId(uint256 _id) { require(_id < 0x100000000); _; } // activePointVoter(): require that :msg.sender can vote as _point, // and that _point is active // modifier activePointVoter(uint32 _point) { require( azimuth.canVoteAs(_point, msg.sender) && azimuth.isActive(_point) ); _; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"constant":true,"inputs":[{"name":"_interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_galaxy","type":"uint8"},{"name":"_proposal","type":"bytes32"}],"name":"startDocumentPoll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_point","type":"uint32"}],"name":"detach","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"name":"approved","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_approved","type":"address"},{"name":"_tokenId","type":"uint256"}],"name":"approve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_proposal","type":"bytes32"}],"name":"updateDocumentPoll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"onUpgrade","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"InterfaceId_ERC165","outputs":[{"name":"","type":"bytes4"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_point","type":"uint32"},{"name":"_target","type":"address"},{"name":"_reset","type":"bool"}],"name":"transferPoint","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_galaxy","type":"uint8"},{"name":"_target","type":"address"}],"name":"createGalaxy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_point","type":"uint32"},{"name":"_transferProxy","type":"address"}],"name":"setTransferProxy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_point","type":"uint32"},{"name":"_encryptionKey","type":"bytes32"},{"name":"_authenticationKey","type":"bytes32"},{"name":"_cryptoSuiteVersion","type":"uint32"},{"name":"_discontinuous","type":"bool"}],"name":"configureKeys","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_point","type":"uint32"},{"name":"_sponsor","type":"uint32"}],"name":"canEscapeTo","outputs":[{"name":"canEscape","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"exists","outputs":[{"name":"doesExist","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_galaxy","type":"uint8"},{"name":"_proposal","type":"address"},{"name":"_vote","type":"bool"}],"name":"castUpgradeVote","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_proposal","type":"address"}],"name":"updateUpgradePoll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"name":"owner","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_galaxy","type":"uint8"},{"name":"_proposal","type":"bytes32"},{"name":"_vote","type":"bool"}],"name":"castDocumentVote","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_point","type":"uint32"},{"name":"_manager","type":"address"}],"name":"setManagementProxy","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":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_galaxy","type":"uint8"},{"name":"_proposal","type":"address"}],"name":"startUpgradePoll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_point","type":"uint32"},{"name":"_target","type":"address"}],"name":"spawn","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_operator","type":"address"},{"name":"_approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_galaxy","type":"uint8"},{"name":"_voter","type":"address"}],"name":"setVotingProxy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_prefix","type":"uint16"},{"name":"_spawnProxy","type":"address"}],"name":"setSpawnProxy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"},{"name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_primary","type":"string"},{"name":"_secondary","type":"string"},{"name":"_tertiary","type":"string"}],"name":"setDnsDomains","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_point","type":"uint32"}],"name":"reject","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_point","type":"uint32"},{"name":"_sponsor","type":"uint32"}],"name":"escape","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_point","type":"uint32"}],"name":"adopt","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_point","type":"uint32"}],"name":"cancelEscape","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"name":"_tokenURI","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"azimuth","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"claims","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"polls","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"name":"result","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"previousEcliptic","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_point","type":"uint32"},{"name":"_time","type":"uint256"}],"name":"getSpawnLimit","outputs":[{"name":"limit","type":"uint32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_previous","type":"address"},{"name":"_azimuth","type":"address"},{"name":"_polls","type":"address"},{"name":"_claims","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_owner","type":"address"},{"indexed":true,"name":"_approved","type":"address"},{"indexed":false,"name":"_tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_owner","type":"address"},{"indexed":true,"name":"_operator","type":"address"},{"indexed":false,"name":"_approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"to","type":"address"}],"name":"Upgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"}],"name":"OwnershipRenounced","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"}]
Contract Creation Code
60806040523480156200001157600080fd5b5060405160808062004be683398101604090815281516020830151918301516060909301516000805433600160a060020a031991821617909155600180548216600160a060020a038087169190911790915560038054831682861617905560028054909216908616179055909290620000b37f01ffc9a70000000000000000000000000000000000000000000000000000000064010000000062000174810204565b60058054600160a060020a031916600160a060020a038316179055620001027f80ac58cd0000000000000000000000000000000000000000000000000000000064010000000062000174810204565b620001367f5b5e139f0000000000000000000000000000000000000000000000000000000064010000000062000174810204565b6200016a7f7f5828d00000000000000000000000000000000000000000000000000000000064010000000062000174810204565b50505050620001e1565b7fffffffff000000000000000000000000000000000000000000000000000000008082161415620001a457600080fd5b7fffffffff00000000000000000000000000000000000000000000000000000000166000908152600460205260409020805460ff19166001179055565b6149f580620001f16000396000f30060806040526004361061020b5763ffffffff60e060020a60003504166301ffc9a7811461021057806305bbf5db1461024657806306fdde0314610266578063073a7804146102f0578063081812fc1461030e578063095ea7b314610342578063172a735c146103665780631824a46b1461037e57806319fa8f50146103935780631e79a85b146103c557806323b872dd146103f457806326295b521461041e5780632c7ba5641461044557806342842e0e1461046f5780634447e48c146104995780634a013296146104ca5780634f558e79146104ee57806351de5541146105065780635623715b146105325780636352211e146105535780636eb582241461056b57806370a082311461058e578063715018a6146105c15780638866bb2c146105d65780638da5cb5b1461060057806395d89b41146106155780639e988d131461062a578063a0d3253f14610651578063a22cb4651461067b578063a60e8bd6146106a1578063ae326221146106c8578063b88d4fde146106f0578063bac55edd1461075f578063bbe21ca514610797578063bf5772b9146107b5578063c1b9d98b146107d9578063c6d761d4146107f7578063c87b56dd14610815578063d40ffacb1461082d578063dcc59b6f14610842578063e64853c414610857578063e985e9c51461086c578063ed969f6814610893578063ef20bff8146108a8578063f2fde38b146108e2575b600080fd5b34801561021c57600080fd5b50610232600160e060020a031960043516610903565b604080519115158252519081900360200190f35b34801561025257600080fd5b5061026460ff60043516602435610922565b005b34801561027257600080fd5b5061027b610ac1565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102b557818101518382015260200161029d565b50505050905090810190601f1680156102e25780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156102fc57600080fd5b5061026463ffffffff60043516610af8565b34801561031a57600080fd5b50610326600435610d39565b60408051600160a060020a039092168252519081900360200190f35b34801561034e57600080fd5b50610264600160a060020a0360043516602435610e79565b34801561037257600080fd5b50610264600435610e9a565b34801561038a57600080fd5b50610264610f2b565b34801561039f57600080fd5b506103a861106a565b60408051600160e060020a03199092168252519081900360200190f35b3480156103d157600080fd5b5061026463ffffffff60043516600160a060020a0360243516604435151561108e565b34801561040057600080fd5b50610264600160a060020a03600435811690602435166044356118d3565b34801561042a57600080fd5b5061026460ff60043516600160a060020a036024351661198b565b34801561045157600080fd5b5061026463ffffffff60043516600160a060020a0360243516611af0565b34801561047b57600080fd5b50610264600160a060020a0360043581169060243516604435611ced565b3480156104a557600080fd5b5061026463ffffffff6004358116906024359060443590606435166084351515611d09565b3480156104d657600080fd5b5061023263ffffffff60043581169060243516611f66565b3480156104fa57600080fd5b506102326004356121dd565b34801561051257600080fd5b5061026460ff60043516600160a060020a03602435166044351515612277565b34801561053e57600080fd5b50610264600160a060020a0360043516612448565b34801561055f57600080fd5b506103266004356124f0565b34801561057757600080fd5b5061026460ff60043516602435604435151561261f565b34801561059a57600080fd5b506105af600160a060020a03600435166127e5565b60408051918252519081900360200190f35b3480156105cd57600080fd5b50610264612864565b3480156105e257600080fd5b5061026463ffffffff60043516600160a060020a03602435166128d0565b34801561060c57600080fd5b50610326612a5f565b34801561062157600080fd5b5061027b612a6e565b34801561063657600080fd5b5061026460ff60043516600160a060020a0360243516612aa5565b34801561065d57600080fd5b5061026463ffffffff60043516600160a060020a0360243516612caf565b34801561068757600080fd5b50610264600160a060020a036004351660243515156131af565b3480156106ad57600080fd5b5061026460ff60043516600160a060020a0360243516613297565b3480156106d457600080fd5b5061026461ffff60043516600160a060020a0360243516613423565b3480156106fc57600080fd5b50604080516020601f60643560048181013592830184900484028501840190955281845261026494600160a060020a0381358116956024803590921695604435953695608494019181908401838280828437509497506135b19650505050505050565b34801561076b57600080fd5b50610264602460048035828101929082013591813580830192908201359160443591820191013561371b565b3480156107a357600080fd5b5061026463ffffffff600435166137f4565b3480156107c157600080fd5b5061026463ffffffff60043581169060243516613a1a565b3480156107e557600080fd5b5061026463ffffffff60043516613bd4565b34801561080357600080fd5b5061026463ffffffff60043516613dfa565b34801561082157600080fd5b5061027b600435613fab565b34801561083957600080fd5b5061032661425e565b34801561084e57600080fd5b5061032661426d565b34801561086357600080fd5b5061032661427c565b34801561087857600080fd5b50610232600160a060020a036004358116906024351661428b565b34801561089f57600080fd5b506103266142fe565b3480156108b457600080fd5b506108c963ffffffff6004351660243561430d565b6040805163ffffffff9092168252519081900360200190f35b3480156108ee57600080fd5b50610264600160a060020a0360043516614403565b600160e060020a03191660009081526004602052604090205460ff1690565b6001546040805160e060020a63b65afedd02815260ff85166004820181905233602483015291519192600160a060020a03169163b65afedd916044808201926020929091908290030181600087803b15801561097d57600080fd5b505af1158015610991573d6000803e3d6000fd5b505050506040513d60208110156109a757600080fd5b50518015610a3357506001546040805160e060020a635e19b30502815263ffffffff841660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b158015610a0657600080fd5b505af1158015610a1a573d6000803e3d6000fd5b505050506040513d6020811015610a3057600080fd5b50515b1515610a3e57600080fd5b600254604080517f9a33aff9000000000000000000000000000000000000000000000000000000008152600481018590529051600160a060020a0390921691639a33aff99160248082019260009290919082900301818387803b158015610aa457600080fd5b505af1158015610ab8573d6000803e3d6000fd5b50505050505050565b60408051808201909152600e81527f417a696d75746820506f696e7473000000000000000000000000000000000000602082015290565b600154604080517f77eb4c5000000000000000000000000000000000000000000000000000000000815263ffffffff841660048201529051600160a060020a03909216916377eb4c50916024808201926020929091908290030181600087803b158015610b6457600080fd5b505af1158015610b78573d6000803e3d6000fd5b505050506040513d6020811015610b8e57600080fd5b50518015610ca85750600154604080517f439f7d3c00000000000000000000000000000000000000000000000000000000815263ffffffff841660048201529051600160a060020a0390921691639137fe0a91839163439f7d3c916024808201926020929091908290030181600087803b158015610c0b57600080fd5b505af1158015610c1f573d6000803e3d6000fd5b505050506040513d6020811015610c3557600080fd5b50516040805163ffffffff84811660e060020a02825290921660048301523360248301525160448083019260209291908290030181600087803b158015610c7b57600080fd5b505af1158015610c8f573d6000803e3d6000fd5b505050506040513d6020811015610ca557600080fd5b50515b1515610cb357600080fd5b600154604080517fbc562b9e00000000000000000000000000000000000000000000000000000000815263ffffffff841660048201529051600160a060020a039092169163bc562b9e9160248082019260009290919082900301818387803b158015610d1e57600080fd5b505af1158015610d32573d6000803e3d6000fd5b5050505050565b6000816401000000008110610d4d57600080fd5b6001546040805160e060020a635e19b30502815263ffffffff861660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b158015610da357600080fd5b505af1158015610db7573d6000803e3d6000fd5b505050506040513d6020811015610dcd57600080fd5b50511515610dda57600080fd5b600154604080517f24541f7800000000000000000000000000000000000000000000000000000000815263ffffffff861660048201529051600160a060020a03909216916324541f78916024808201926020929091908290030181600087803b158015610e4657600080fd5b505af1158015610e5a573d6000803e3d6000fd5b505050506040513d6020811015610e7057600080fd5b50519392505050565b806401000000008110610e8b57600080fd5b610e958284611af0565b505050565b600254604080517f172a735c000000000000000000000000000000000000000000000000000000008152600481018490529051600160a060020a039092169163172a735c916024808201926020929091908290030181600087803b158015610f0157600080fd5b505af1158015610f15573d6000803e3d6000fd5b505050506040513d6020811015610e9557600080fd5b600354600160a060020a031633148015610fcb5750600160009054906101000a9004600160a060020a0316600160a060020a0316638da5cb5b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015610f9357600080fd5b505af1158015610fa7573d6000803e3d6000fd5b505050506040513d6020811015610fbd57600080fd5b5051600160a060020a031630145b801561105d5750600260009054906101000a9004600160a060020a0316600160a060020a0316638da5cb5b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561102557600080fd5b505af1158015611039573d6000803e3d6000fd5b505050506040513d602081101561104f57600080fd5b5051600160a060020a031630145b151561106857600080fd5b565b7f01ffc9a70000000000000000000000000000000000000000000000000000000081565b600154604080517f728aa85700000000000000000000000000000000000000000000000000000000815263ffffffff861660048201523360248201529051600092600160a060020a03169163728aa85791604480830192602092919082900301818787803b1580156110ff57600080fd5b505af1158015611113573d6000803e3d6000fd5b505050506040513d602081101561112957600080fd5b5051151561113657600080fd5b6001546040805160e060020a635e19b30502815263ffffffff871660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b15801561118c57600080fd5b505af11580156111a0573d6000803e3d6000fd5b505050506040513d60208110156111b657600080fd5b5051151561124257600154604080517f7bc702a100000000000000000000000000000000000000000000000000000000815263ffffffff871660048201529051600160a060020a0390921691637bc702a19160248082019260009290919082900301818387803b15801561122957600080fd5b505af115801561123d573d6000803e3d6000fd5b505050505b6001546040805160e060020a63caf590f902815263ffffffff87166004820152600160a060020a0386811660248301529151919092169163caf590f99160448083019260209291908290030181600087803b1580156112a057600080fd5b505af11580156112b4573d6000803e3d6000fd5b505050506040513d60208110156112ca57600080fd5b5051151561149b576001546040805160e160020a63310d91f102815263ffffffff871660048201529051600160a060020a039092169163621b23e2916024808201926020929091908290030181600087803b15801561132857600080fd5b505af115801561133c573d6000803e3d6000fd5b505050506040513d602081101561135257600080fd5b5051600154604080517fddc3595000000000000000000000000000000000000000000000000000000000815263ffffffff88166004820152600160a060020a038781166024830152915193945091169163ddc359509160448082019260009290919082900301818387803b1580156113c957600080fd5b505af11580156113dd573d6000803e3d6000fd5b50506001546040805160e260020a630b1ee95902815263ffffffff891660048201526000602482018190529151600160a060020a039093169450632c7ba56493506044808201939182900301818387803b15801561143a57600080fd5b505af115801561144e573d6000803e3d6000fd5b50506040805163ffffffff881681529051600160a060020a038088169450851692507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35b81156118cd576001546040805160e060020a636d09887b02815263ffffffff871660048201529051600160a060020a0390921691636d09887b916024808201926020929091908290030181600087803b1580156114f757600080fd5b505af115801561150b573d6000803e3d6000fd5b505050506040513d602081101561152157600080fd5b50511561164157600154604080517ff491491900000000000000000000000000000000000000000000000000000000815263ffffffff871660048201529051600160a060020a039092169163f49149199160248082019260009290919082900301818387803b15801561159357600080fd5b505af11580156115a7573d6000803e3d6000fd5b5050600154604080517ff9b87d4000000000000000000000000000000000000000000000000000000000815263ffffffff8916600482015260006024820181905260448201819052606482018190529151600160a060020a03909316945063f9b87d4093506084808201939182900301818387803b15801561162857600080fd5b505af115801561163c573d6000803e3d6000fd5b505050505b600154604080517f8866bb2c00000000000000000000000000000000000000000000000000000000815263ffffffff871660048201526000602482018190529151600160a060020a0390931692638866bb2c9260448084019391929182900301818387803b1580156116b257600080fd5b505af11580156116c6573d6000803e3d6000fd5b5050600154604080517fa297c1d800000000000000000000000000000000000000000000000000000000815263ffffffff891660048201526000602482018190529151600160a060020a03909316945063a297c1d893506044808201939182900301818387803b15801561173957600080fd5b505af115801561174d573d6000803e3d6000fd5b50506001546040805160e260020a630b1ee95902815263ffffffff891660048201526000602482018190529151600160a060020a039093169450632c7ba56493506044808201939182900301818387803b1580156117aa57600080fd5b505af11580156117be573d6000803e3d6000fd5b5050600154604080517f2a19642c00000000000000000000000000000000000000000000000000000000815263ffffffff891660048201526000602482018190529151600160a060020a039093169450632a19642c93506044808201939182900301818387803b15801561183157600080fd5b505af1158015611845573d6000803e3d6000fd5b5050600554604080517feaae46e500000000000000000000000000000000000000000000000000000000815263ffffffff891660048201529051600160a060020a03909216935063eaae46e5925060248082019260009290919082900301818387803b1580156118b457600080fd5b505af11580156118c8573d6000803e3d6000fd5b505050505b50505050565b60008164010000000081106118e757600080fd5b6001546040805160e060020a63caf590f902815263ffffffff86166004820152600160a060020a0388811660248301529151869550919092169163caf590f99160448083019260209291908290030181600087803b15801561194857600080fd5b505af115801561195c573d6000803e3d6000fd5b505050506040513d602081101561197257600080fd5b5051151561197f57600080fd5b610d328285600161108e565b600054600160a060020a031633146119a257600080fd5b6001546040805160e060020a63caf590f902815260ff851660048201526000602482018190529151600160a060020a039093169263caf590f992604480840193602093929083900390910190829087803b1580156119ff57600080fd5b505af1158015611a13573d6000803e3d6000fd5b505050506040513d6020811015611a2957600080fd5b50518015611a3f5750600160a060020a03811615155b1515611a4a57600080fd5b600260009054906101000a9004600160a060020a0316600160a060020a031663246d41a96040518163ffffffff1660e060020a028152600401600060405180830381600087803b158015611a9d57600080fd5b505af1158015611ab1573d6000803e3d6000fd5b50505050600160a060020a038116331415611adc57611ad78260ff168260016000614426565b611aec565b611aec8260ff1682600033614426565b5050565b6001546040805160e160020a63310d91f102815263ffffffff851660048201529051600092600160a060020a03169163621b23e291602480830192602092919082900301818787803b158015611b4557600080fd5b505af1158015611b59573d6000803e3d6000fd5b505050506040513d6020811015611b6f57600080fd5b50519050600160a060020a038116331480611c205750600154604080517fb6363cf2000000000000000000000000000000000000000000000000000000008152600160a060020a0384811660048301523360248301529151919092169163b6363cf29160448083019260209291908290030181600087803b158015611bf357600080fd5b505af1158015611c07573d6000803e3d6000fd5b505050506040513d6020811015611c1d57600080fd5b50515b1515611c2b57600080fd5b6001546040805160e260020a630b1ee95902815263ffffffff86166004820152600160a060020a03858116602483015291519190921691632c7ba56491604480830192600092919082900301818387803b158015611c8857600080fd5b505af1158015611c9c573d6000803e3d6000fd5b50506040805163ffffffff871681529051600160a060020a038087169450851692507f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360200190a3505050565b610e9583838360206040519081016040528060008152506135b1565b600154604080517f9137fe0a00000000000000000000000000000000000000000000000000000000815263ffffffff8816600482015233602482015290518792600160a060020a031691639137fe0a9160448083019260209291908290030181600087803b158015611d7a57600080fd5b505af1158015611d8e573d6000803e3d6000fd5b505050506040513d6020811015611da457600080fd5b50518015611e3057506001546040805160e060020a635e19b30502815263ffffffff841660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b158015611e0357600080fd5b505af1158015611e17573d6000803e3d6000fd5b505050506040513d6020811015611e2d57600080fd5b50515b1515611e3b57600080fd5b8115611ec557600154604080517ff491491900000000000000000000000000000000000000000000000000000000815263ffffffff891660048201529051600160a060020a039092169163f49149199160248082019260009290919082900301818387803b158015611eac57600080fd5b505af1158015611ec0573d6000803e3d6000fd5b505050505b600154604080517ff9b87d4000000000000000000000000000000000000000000000000000000000815263ffffffff808a1660048301526024820189905260448201889052861660648201529051600160a060020a039092169163f9b87d409160848082019260009290919082900301818387803b158015611f4657600080fd5b505af1158015611f5a573d6000803e3d6000fd5b50505050505050505050565b6001546040805160e060020a636d09887b02815263ffffffff84166004820152905160009283928392600160a060020a0390921691636d09887b9160248082019260209290919082900301818787803b158015611fc257600080fd5b505af1158015611fd6573d6000803e3d6000fd5b505050506040513d6020811015611fec57600080fd5b50511515611ffd57600092506121d5565b6001546040805160e060020a639397640502815263ffffffff881660048201529051600160a060020a03909216916393976405916024808201926020929091908290030181600087803b15801561205357600080fd5b505af1158015612067573d6000803e3d6000fd5b505050506040513d602081101561207d57600080fd5b50516001546040805160e060020a639397640502815263ffffffff881660048201529051929450600160a060020a03909116916393976405916024808201926020929091908290030181600087803b1580156120d857600080fd5b505af11580156120ec573d6000803e3d6000fd5b505050506040513d602081101561210257600080fd5b5051905081600281111561211257fe5b60ff1681600281111561212157fe5b60010160ff1614806121d2575081600281111561213a57fe5b81600281111561214657fe5b1480156121d257506001546040805160e060020a636d09887b02815263ffffffff881660048201529051600160a060020a0390921691636d09887b916024808201926020929091908290030181600087803b1580156121a457600080fd5b505af11580156121b8573d6000803e3d6000fd5b505050506040513d60208110156121ce57600080fd5b5051155b92505b505092915050565b60006401000000008210801561227157506001546040805160e060020a635e19b30502815263ffffffff851660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b15801561224457600080fd5b505af1158015612258573d6000803e3d6000fd5b505050506040513d602081101561226e57600080fd5b50515b92915050565b6001546040805160e060020a63b65afedd02815260ff8616600482018190523360248301529151600093600160a060020a03169163b65afedd91604480830192602092919082900301818887803b1580156122d157600080fd5b505af11580156122e5573d6000803e3d6000fd5b505050506040513d60208110156122fb57600080fd5b5051801561238757506001546040805160e060020a635e19b30502815263ffffffff841660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b15801561235a57600080fd5b505af115801561236e573d6000803e3d6000fd5b505050506040513d602081101561238457600080fd5b50515b151561239257600080fd5b600254604080517f51de554100000000000000000000000000000000000000000000000000000000815260ff88166004820152600160a060020a0387811660248301528615156044830152915191909216916351de55419160648083019260209291908290030181600087803b15801561240b57600080fd5b505af115801561241f573d6000803e3d6000fd5b505050506040513d602081101561243557600080fd5b505191508115610d3257610d32846147a7565b600254604080517f5623715b000000000000000000000000000000000000000000000000000000008152600160a060020a03848116600483015291516000939290921691635623715b9160248082019260209290919082900301818787803b1580156124b357600080fd5b505af11580156124c7573d6000803e3d6000fd5b505050506040513d60208110156124dd57600080fd5b505190508015611aec57611aec826147a7565b60008082640100000000811061250557600080fd5b6001546040805160e060020a635e19b30502815263ffffffff871660048201529051869450600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b15801561255e57600080fd5b505af1158015612572573d6000803e3d6000fd5b505050506040513d602081101561258857600080fd5b5051151561259557600080fd5b6001546040805160e160020a63310d91f102815263ffffffff851660048201529051600160a060020a039092169163621b23e2916024808201926020929091908290030181600087803b1580156125eb57600080fd5b505af11580156125ff573d6000803e3d6000fd5b505050506040513d602081101561261557600080fd5b5051949350505050565b6001546040805160e060020a63b65afedd02815260ff86166004820181905233602483015291519192600160a060020a03169163b65afedd916044808201926020929091908290030181600087803b15801561267a57600080fd5b505af115801561268e573d6000803e3d6000fd5b505050506040513d60208110156126a457600080fd5b5051801561273057506001546040805160e060020a635e19b30502815263ffffffff841660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b15801561270357600080fd5b505af1158015612717573d6000803e3d6000fd5b505050506040513d602081101561272d57600080fd5b50515b151561273b57600080fd5b600254604080517f6eb5822400000000000000000000000000000000000000000000000000000000815260ff871660048201526024810186905284151560448201529051600160a060020a0390921691636eb58224916064808201926020929091908290030181600087803b1580156127b357600080fd5b505af11580156127c7573d6000803e3d6000fd5b505050506040513d60208110156127dd57600080fd5b505050505050565b6000600160a060020a03821615156127fc57600080fd5b600154604080517f12afbc78000000000000000000000000000000000000000000000000000000008152600160a060020a038581166004830152915191909216916312afbc789160248083019260209291908290030181600087803b15801561224457600080fd5b600054600160a060020a0316331461287b57600080fd5b60008054604051600160a060020a03909116917ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482091a26000805473ffffffffffffffffffffffffffffffffffffffff19169055565b6001546040805160e060020a63caf590f902815263ffffffff8516600482015233602482015290518492600160a060020a03169163caf590f99160448083019260209291908290030181600087803b15801561292b57600080fd5b505af115801561293f573d6000803e3d6000fd5b505050506040513d602081101561295557600080fd5b505180156129e157506001546040805160e060020a635e19b30502815263ffffffff841660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b1580156129b457600080fd5b505af11580156129c8573d6000803e3d6000fd5b505050506040513d60208110156129de57600080fd5b50515b15156129ec57600080fd5b600154604080517f8866bb2c00000000000000000000000000000000000000000000000000000000815263ffffffff86166004820152600160a060020a03858116602483015291519190921691638866bb2c91604480830192600092919082900301818387803b158015610aa457600080fd5b600054600160a060020a031681565b60408051808201909152600381527f415a500000000000000000000000000000000000000000000000000000000000602082015290565b6001546040805160e060020a63b65afedd02815260ff85166004820181905233602483015291519192600160a060020a03169163b65afedd916044808201926020929091908290030181600087803b158015612b0057600080fd5b505af1158015612b14573d6000803e3d6000fd5b505050506040513d6020811015612b2a57600080fd5b50518015612bb657506001546040805160e060020a635e19b30502815263ffffffff841660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b158015612b8957600080fd5b505af1158015612b9d573d6000803e3d6000fd5b505050506040513d6020811015612bb357600080fd5b50515b1515612bc157600080fd5b30600160a060020a031682600160a060020a031663ed969f686040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015612c0957600080fd5b505af1158015612c1d573d6000803e3d6000fd5b505050506040513d6020811015612c3357600080fd5b5051600160a060020a031614612c4857600080fd5b600254604080517fe31f3e0c000000000000000000000000000000000000000000000000000000008152600160a060020a0385811660048301529151919092169163e31f3e0c91602480830192600092919082900301818387803b158015610aa457600080fd5b6001546040805160e060020a63caf590f902815263ffffffff8516600482015260006024820181905291519192600160a060020a03169163caf590f99160448082019260209290919082900301818787803b158015612d0d57600080fd5b505af1158015612d21573d6000803e3d6000fd5b505050506040513d6020811015612d3757600080fd5b50511515612d4457600080fd5b600154604080517fe4a358d700000000000000000000000000000000000000000000000000000000815263ffffffff861660048201529051600160a060020a039092169163e4a358d7916024808201926020929091908290030181600087803b158015612db057600080fd5b505af1158015612dc4573d6000803e3d6000fd5b505050506040513d6020811015612dda57600080fd5b50516001546040805160e060020a639397640502815263ffffffff871660048201529051929350600160a060020a03909116916393976405916024808201926020929091908290030181600087803b158015612e3557600080fd5b505af1158015612e49573d6000803e3d6000fd5b505050506040513d6020811015612e5f57600080fd5b50516002811115612e6c57fe5b6001546040805160e060020a639397640502815261ffff85166004820152905160ff9390931692600160a060020a03909216916393976405916024808201926020929091908290030181600087803b158015612ec757600080fd5b505af1158015612edb573d6000803e3d6000fd5b505050506040513d6020811015612ef157600080fd5b50516002811115612efe57fe5b60010160ff16141515612f1057600080fd5b6001546040805160e060020a636d09887b02815261ffff841660048201529051600160a060020a0390921691636d09887b916024808201926020929091908290030181600087803b158015612f6457600080fd5b505af1158015612f78573d6000803e3d6000fd5b505050506040513d6020811015612f8e57600080fd5b5051801561304d5750612fa58161ffff164261430d565b600154604080517f293a916900000000000000000000000000000000000000000000000000000000815261ffff85166004820152905163ffffffff9390931692600160a060020a039092169163293a9169916024808201926020929091908290030181600087803b15801561301957600080fd5b505af115801561302d573d6000803e3d6000fd5b505050506040513d602081101561304357600080fd5b505163ffffffff16105b151561305857600080fd5b600154604080517f8a27bf5900000000000000000000000000000000000000000000000000000000815261ffff841660048201523360248201529051600160a060020a0390921691638a27bf59916044808201926020929091908290030181600087803b1580156130c857600080fd5b505af11580156130dc573d6000803e3d6000fd5b505050506040513d60208110156130f257600080fd5b505115156130ff57600080fd5b33600160a060020a03831614156131235761311e838360016000614426565b610e95565b6001546040805160e160020a63310d91f102815261ffff841660048201529051610e959286928692600092600160a060020a03169163621b23e291602480830192602092919082900301818787803b15801561317e57600080fd5b505af1158015613192573d6000803e3d6000fd5b505050506040513d60208110156131a857600080fd5b5051614426565b600160a060020a03821615156131c457600080fd5b600154604080517fbc735d90000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a03858116602483015284151560448301529151919092169163bc735d9091606480830192600092919082900301818387803b15801561323957600080fd5b505af115801561324d573d6000803e3d6000fd5b50506040805184151581529051600160a060020a03861693503392507f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c319181900360200190a35050565b6001546040805160e060020a63caf590f902815260ff85166004820181905233602483015291519192600160a060020a03169163caf590f9916044808201926020929091908290030181600087803b1580156132f257600080fd5b505af1158015613306573d6000803e3d6000fd5b505050506040513d602081101561331c57600080fd5b505180156133a857506001546040805160e060020a635e19b30502815263ffffffff841660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b15801561337b57600080fd5b505af115801561338f573d6000803e3d6000fd5b505050506040513d60208110156133a557600080fd5b50515b15156133b357600080fd5b600154604080517fa297c1d800000000000000000000000000000000000000000000000000000000815260ff86166004820152600160a060020a0385811660248301529151919092169163a297c1d891604480830192600092919082900301818387803b158015610aa457600080fd5b6001546040805160e060020a63caf590f902815261ffff85166004820181905233602483015291519192600160a060020a03169163caf590f9916044808201926020929091908290030181600087803b15801561347f57600080fd5b505af1158015613493573d6000803e3d6000fd5b505050506040513d60208110156134a957600080fd5b5051801561353557506001546040805160e060020a635e19b30502815263ffffffff841660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b15801561350857600080fd5b505af115801561351c573d6000803e3d6000fd5b505050506040513d602081101561353257600080fd5b50515b151561354057600080fd5b600154604080517f2a19642c00000000000000000000000000000000000000000000000000000000815261ffff86166004820152600160a060020a03858116602483015291519190921691632a19642c91604480830192600092919082900301818387803b158015610aa457600080fd5b60006135be8585856118d3565b6135d084600160a060020a0316614944565b15610d32576040517f150b7a020000000000000000000000000000000000000000000000000000000081523360048201818152600160a060020a038881166024850152604484018790526080606485019081528651608486015286519189169463150b7a0294938b938a938a93909160a490910190602085019080838360005b83811015613668578181015183820152602001613650565b50505050905090810190601f1680156136955780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b1580156136b757600080fd5b505af11580156136cb573d6000803e3d6000fd5b505050506040513d60208110156136e157600080fd5b50519050600160e060020a031981167f150b7a020000000000000000000000000000000000000000000000000000000014610d3257600080fd5b600054600160a060020a0316331461373257600080fd5b6001546040517fbac55edd00000000000000000000000000000000000000000000000000000000815260606004820190815260648201889052600160a060020a039092169163bac55edd918991899189918991899189918190602481019060448101906084018a8a80828437909101858103845288815260200190508888808284379091018581038352868152602001905086868082843782019150509950505050505050505050600060405180830381600087803b158015611f4657600080fd5b600154604080517f9b350e1200000000000000000000000000000000000000000000000000000000815263ffffffff841660048201529051600160a060020a0390921691639b350e12916024808201926020929091908290030181600087803b15801561386057600080fd5b505af1158015613874573d6000803e3d6000fd5b505050506040513d602081101561388a57600080fd5b505180156139a45750600154604080517ff5af662100000000000000000000000000000000000000000000000000000000815263ffffffff841660048201529051600160a060020a0390921691639137fe0a91839163f5af6621916024808201926020929091908290030181600087803b15801561390757600080fd5b505af115801561391b573d6000803e3d6000fd5b505050506040513d602081101561393157600080fd5b50516040805163ffffffff84811660e060020a02825290921660048301523360248301525160448083019260209291908290030181600087803b15801561397757600080fd5b505af115801561398b573d6000803e3d6000fd5b505050506040513d60208110156139a157600080fd5b50515b15156139af57600080fd5b600154604080517fc6d761d400000000000000000000000000000000000000000000000000000000815263ffffffff841660048201529051600160a060020a039092169163c6d761d49160248082019260009290919082900301818387803b158015610d1e57600080fd5b600154604080517f9137fe0a00000000000000000000000000000000000000000000000000000000815263ffffffff8516600482015233602482015290518492600160a060020a031691639137fe0a9160448083019260209291908290030181600087803b158015613a8b57600080fd5b505af1158015613a9f573d6000803e3d6000fd5b505050506040513d6020811015613ab557600080fd5b50518015613b4157506001546040805160e060020a635e19b30502815263ffffffff841660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b158015613b1457600080fd5b505af1158015613b28573d6000803e3d6000fd5b505050506040513d6020811015613b3e57600080fd5b50515b1515613b4c57600080fd5b613b568383611f66565b1515613b6157600080fd5b600154604080517fa634585900000000000000000000000000000000000000000000000000000000815263ffffffff8087166004830152851660248201529051600160a060020a039092169163a63458599160448082019260009290919082900301818387803b158015610aa457600080fd5b600154604080517f9b350e1200000000000000000000000000000000000000000000000000000000815263ffffffff841660048201529051600160a060020a0390921691639b350e12916024808201926020929091908290030181600087803b158015613c4057600080fd5b505af1158015613c54573d6000803e3d6000fd5b505050506040513d6020811015613c6a57600080fd5b50518015613d845750600154604080517ff5af662100000000000000000000000000000000000000000000000000000000815263ffffffff841660048201529051600160a060020a0390921691639137fe0a91839163f5af6621916024808201926020929091908290030181600087803b158015613ce757600080fd5b505af1158015613cfb573d6000803e3d6000fd5b505050506040513d6020811015613d1157600080fd5b50516040805163ffffffff84811660e060020a02825290921660048301523360248301525160448083019260209291908290030181600087803b158015613d5757600080fd5b505af1158015613d6b573d6000803e3d6000fd5b505050506040513d6020811015613d8157600080fd5b50515b1515613d8f57600080fd5b600154604080517f1306318000000000000000000000000000000000000000000000000000000000815263ffffffff841660048201529051600160a060020a039092169163130631809160248082019260009290919082900301818387803b158015610d1e57600080fd5b600154604080517f9137fe0a00000000000000000000000000000000000000000000000000000000815263ffffffff8416600482015233602482015290518392600160a060020a031691639137fe0a9160448083019260209291908290030181600087803b158015613e6b57600080fd5b505af1158015613e7f573d6000803e3d6000fd5b505050506040513d6020811015613e9557600080fd5b50518015613f2157506001546040805160e060020a635e19b30502815263ffffffff841660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b158015613ef457600080fd5b505af1158015613f08573d6000803e3d6000fd5b505050506040513d6020811015613f1e57600080fd5b50515b1515613f2c57600080fd5b600154604080517fc6d761d400000000000000000000000000000000000000000000000000000000815263ffffffff851660048201529051600160a060020a039092169163c6d761d49160248082019260009290919082900301818387803b158015613f9757600080fd5b505af11580156127dd573d6000803e3d6000fd5b606080826401000000008110613fc057600080fd5b60408051606081018252602e81527f68747470733a2f2f617a696d7574682e6e6574776f726b2f6572633732312f3060208201527f3030303030303030302e6a736f6e0000000000000000000000000000000000009181019190915292508291507fff00000000000000000000000000000000000000000000000000000000000000600a633b9aca0086040660300160f860020a0216600081901a603f84015350600a6305f5e10085040660300160f860020a0282602081518110151561408357fe5b906020010190600160f860020a031916908160001a905350600a6298968085040660300160f860020a028260218151811015156140bc57fe5b906020010190600160f860020a031916908160001a905350600a620f424085040660300160f860020a028260228151811015156140f557fe5b906020010190600160f860020a031916908160001a905350600a620186a085040660300160f860020a0282602381518110151561412e57fe5b906020010190600160f860020a031916908160001a905350600a61271085040660300160f860020a0282602481518110151561416657fe5b906020010190600160f860020a031916908160001a905350600a6103e885040660300160f860020a0282602581518110151561419e57fe5b906020010190600160f860020a031916908160001a905350600a606485040660300160f860020a028260268151811015156141d557fe5b906020010190600160f860020a031916908160001a905350600a8085040660300160f860020a0282602781518110151561420b57fe5b906020010190600160f860020a031916908160001a905350600a840660300160f860020a0282602881518110151561423f57fe5b906020010190600160f860020a031916908160001a9053505050919050565b600154600160a060020a031681565b600554600160a060020a031681565b600254600160a060020a031681565b600154604080517fb6363cf2000000000000000000000000000000000000000000000000000000008152600160a060020a03858116600483015284811660248301529151600093929092169163b6363cf29160448082019260209290919082900301818787803b158015610e4657600080fd5b600354600160a060020a031681565b6001546040805160e060020a639397640502815263ffffffff85166004820152905160009283928392600160a060020a039092169163939764059160248082019260209290919082900301818787803b15801561436957600080fd5b505af115801561437d573d6000803e3d6000fd5b505050506040513d602081101561439357600080fd5b5051915060008260028111156143a557fe5b14156143b45760ff92506121d5565b60018260028111156143c257fe5b14156143fa57506301e13380635c2aad7f1984010460068110156143ef578060020a6104000292506143f5565b61ffff92505b6121d5565b600092506121d5565b600054600160a060020a0316331461441a57600080fd5b6144238161494c565b50565b600154604080517fc17ad9d800000000000000000000000000000000000000000000000000000000815263ffffffff871660048201529051600160a060020a039092169163c17ad9d89160248082019260009290919082900301818387803b15801561449157600080fd5b505af11580156144a5573d6000803e3d6000fd5b50505050811561460957600154604080517f7bc702a100000000000000000000000000000000000000000000000000000000815263ffffffff871660048201529051600160a060020a0390921691637bc702a19160248082019260009290919082900301818387803b15801561451a57600080fd5b505af115801561452e573d6000803e3d6000fd5b5050600154604080517fddc3595000000000000000000000000000000000000000000000000000000000815263ffffffff89166004820152600160a060020a038881166024830152915191909216935063ddc359509250604480830192600092919082900301818387803b1580156145a557600080fd5b505af11580156145b9573d6000803e3d6000fd5b50506040805163ffffffff881681529051600160a060020a0387169350600092507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a36118cd565b600154604080517fddc3595000000000000000000000000000000000000000000000000000000000815263ffffffff87166004820152600160a060020a0384811660248301529151919092169163ddc3595091604480830192600092919082900301818387803b15801561467c57600080fd5b505af1158015614690573d6000803e3d6000fd5b50506001546040805160e260020a630b1ee95902815263ffffffff89166004820152600160a060020a0388811660248301529151919092169350632c7ba5649250604480830192600092919082900301818387803b1580156146f157600080fd5b505af1158015614705573d6000803e3d6000fd5b50506040805163ffffffff881681529051600160a060020a0385169350600092507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a382600160a060020a031681600160a060020a03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258663ffffffff166040518082815260200191505060405180910390a350505050565b600154604080517ff2fde38b000000000000000000000000000000000000000000000000000000008152600160a060020a0384811660048301529151919092169163f2fde38b91602480830192600092919082900301818387803b15801561480e57600080fd5b505af1158015614822573d6000803e3d6000fd5b5050600254604080517ff2fde38b000000000000000000000000000000000000000000000000000000008152600160a060020a038681166004830152915191909216935063f2fde38b9250602480830192600092919082900301818387803b15801561488d57600080fd5b505af11580156148a1573d6000803e3d6000fd5b5050505080600160a060020a0316631824a46b6040518163ffffffff1660e060020a028152600401600060405180830381600087803b1580156148e357600080fd5b505af11580156148f7573d6000803e3d6000fd5b505060408051600160a060020a038516815290517fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9350908190036020019150a180600160a060020a0316ff5b6000903b1190565b600160a060020a038116151561496157600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03929092169190911790555600a165627a7a7230582053db0352084252f483a76437bf131ec08201d58fe878f89b3bffa84a3e6d3dad0029000000000000000000000000a23b5d8e86091ab6c14981f404c2864701aa2903000000000000000000000000223c067f8cf28ae173ee5cafea60ca44c335fecb0000000000000000000000007fecab617c868bb5996d99d95200d2fa708218e4000000000000000000000000e7e7f69b34d7d9bd8d61fb22c33b22708947971a
Deployed Bytecode
0x60806040526004361061020b5763ffffffff60e060020a60003504166301ffc9a7811461021057806305bbf5db1461024657806306fdde0314610266578063073a7804146102f0578063081812fc1461030e578063095ea7b314610342578063172a735c146103665780631824a46b1461037e57806319fa8f50146103935780631e79a85b146103c557806323b872dd146103f457806326295b521461041e5780632c7ba5641461044557806342842e0e1461046f5780634447e48c146104995780634a013296146104ca5780634f558e79146104ee57806351de5541146105065780635623715b146105325780636352211e146105535780636eb582241461056b57806370a082311461058e578063715018a6146105c15780638866bb2c146105d65780638da5cb5b1461060057806395d89b41146106155780639e988d131461062a578063a0d3253f14610651578063a22cb4651461067b578063a60e8bd6146106a1578063ae326221146106c8578063b88d4fde146106f0578063bac55edd1461075f578063bbe21ca514610797578063bf5772b9146107b5578063c1b9d98b146107d9578063c6d761d4146107f7578063c87b56dd14610815578063d40ffacb1461082d578063dcc59b6f14610842578063e64853c414610857578063e985e9c51461086c578063ed969f6814610893578063ef20bff8146108a8578063f2fde38b146108e2575b600080fd5b34801561021c57600080fd5b50610232600160e060020a031960043516610903565b604080519115158252519081900360200190f35b34801561025257600080fd5b5061026460ff60043516602435610922565b005b34801561027257600080fd5b5061027b610ac1565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102b557818101518382015260200161029d565b50505050905090810190601f1680156102e25780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156102fc57600080fd5b5061026463ffffffff60043516610af8565b34801561031a57600080fd5b50610326600435610d39565b60408051600160a060020a039092168252519081900360200190f35b34801561034e57600080fd5b50610264600160a060020a0360043516602435610e79565b34801561037257600080fd5b50610264600435610e9a565b34801561038a57600080fd5b50610264610f2b565b34801561039f57600080fd5b506103a861106a565b60408051600160e060020a03199092168252519081900360200190f35b3480156103d157600080fd5b5061026463ffffffff60043516600160a060020a0360243516604435151561108e565b34801561040057600080fd5b50610264600160a060020a03600435811690602435166044356118d3565b34801561042a57600080fd5b5061026460ff60043516600160a060020a036024351661198b565b34801561045157600080fd5b5061026463ffffffff60043516600160a060020a0360243516611af0565b34801561047b57600080fd5b50610264600160a060020a0360043581169060243516604435611ced565b3480156104a557600080fd5b5061026463ffffffff6004358116906024359060443590606435166084351515611d09565b3480156104d657600080fd5b5061023263ffffffff60043581169060243516611f66565b3480156104fa57600080fd5b506102326004356121dd565b34801561051257600080fd5b5061026460ff60043516600160a060020a03602435166044351515612277565b34801561053e57600080fd5b50610264600160a060020a0360043516612448565b34801561055f57600080fd5b506103266004356124f0565b34801561057757600080fd5b5061026460ff60043516602435604435151561261f565b34801561059a57600080fd5b506105af600160a060020a03600435166127e5565b60408051918252519081900360200190f35b3480156105cd57600080fd5b50610264612864565b3480156105e257600080fd5b5061026463ffffffff60043516600160a060020a03602435166128d0565b34801561060c57600080fd5b50610326612a5f565b34801561062157600080fd5b5061027b612a6e565b34801561063657600080fd5b5061026460ff60043516600160a060020a0360243516612aa5565b34801561065d57600080fd5b5061026463ffffffff60043516600160a060020a0360243516612caf565b34801561068757600080fd5b50610264600160a060020a036004351660243515156131af565b3480156106ad57600080fd5b5061026460ff60043516600160a060020a0360243516613297565b3480156106d457600080fd5b5061026461ffff60043516600160a060020a0360243516613423565b3480156106fc57600080fd5b50604080516020601f60643560048181013592830184900484028501840190955281845261026494600160a060020a0381358116956024803590921695604435953695608494019181908401838280828437509497506135b19650505050505050565b34801561076b57600080fd5b50610264602460048035828101929082013591813580830192908201359160443591820191013561371b565b3480156107a357600080fd5b5061026463ffffffff600435166137f4565b3480156107c157600080fd5b5061026463ffffffff60043581169060243516613a1a565b3480156107e557600080fd5b5061026463ffffffff60043516613bd4565b34801561080357600080fd5b5061026463ffffffff60043516613dfa565b34801561082157600080fd5b5061027b600435613fab565b34801561083957600080fd5b5061032661425e565b34801561084e57600080fd5b5061032661426d565b34801561086357600080fd5b5061032661427c565b34801561087857600080fd5b50610232600160a060020a036004358116906024351661428b565b34801561089f57600080fd5b506103266142fe565b3480156108b457600080fd5b506108c963ffffffff6004351660243561430d565b6040805163ffffffff9092168252519081900360200190f35b3480156108ee57600080fd5b50610264600160a060020a0360043516614403565b600160e060020a03191660009081526004602052604090205460ff1690565b6001546040805160e060020a63b65afedd02815260ff85166004820181905233602483015291519192600160a060020a03169163b65afedd916044808201926020929091908290030181600087803b15801561097d57600080fd5b505af1158015610991573d6000803e3d6000fd5b505050506040513d60208110156109a757600080fd5b50518015610a3357506001546040805160e060020a635e19b30502815263ffffffff841660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b158015610a0657600080fd5b505af1158015610a1a573d6000803e3d6000fd5b505050506040513d6020811015610a3057600080fd5b50515b1515610a3e57600080fd5b600254604080517f9a33aff9000000000000000000000000000000000000000000000000000000008152600481018590529051600160a060020a0390921691639a33aff99160248082019260009290919082900301818387803b158015610aa457600080fd5b505af1158015610ab8573d6000803e3d6000fd5b50505050505050565b60408051808201909152600e81527f417a696d75746820506f696e7473000000000000000000000000000000000000602082015290565b600154604080517f77eb4c5000000000000000000000000000000000000000000000000000000000815263ffffffff841660048201529051600160a060020a03909216916377eb4c50916024808201926020929091908290030181600087803b158015610b6457600080fd5b505af1158015610b78573d6000803e3d6000fd5b505050506040513d6020811015610b8e57600080fd5b50518015610ca85750600154604080517f439f7d3c00000000000000000000000000000000000000000000000000000000815263ffffffff841660048201529051600160a060020a0390921691639137fe0a91839163439f7d3c916024808201926020929091908290030181600087803b158015610c0b57600080fd5b505af1158015610c1f573d6000803e3d6000fd5b505050506040513d6020811015610c3557600080fd5b50516040805163ffffffff84811660e060020a02825290921660048301523360248301525160448083019260209291908290030181600087803b158015610c7b57600080fd5b505af1158015610c8f573d6000803e3d6000fd5b505050506040513d6020811015610ca557600080fd5b50515b1515610cb357600080fd5b600154604080517fbc562b9e00000000000000000000000000000000000000000000000000000000815263ffffffff841660048201529051600160a060020a039092169163bc562b9e9160248082019260009290919082900301818387803b158015610d1e57600080fd5b505af1158015610d32573d6000803e3d6000fd5b5050505050565b6000816401000000008110610d4d57600080fd5b6001546040805160e060020a635e19b30502815263ffffffff861660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b158015610da357600080fd5b505af1158015610db7573d6000803e3d6000fd5b505050506040513d6020811015610dcd57600080fd5b50511515610dda57600080fd5b600154604080517f24541f7800000000000000000000000000000000000000000000000000000000815263ffffffff861660048201529051600160a060020a03909216916324541f78916024808201926020929091908290030181600087803b158015610e4657600080fd5b505af1158015610e5a573d6000803e3d6000fd5b505050506040513d6020811015610e7057600080fd5b50519392505050565b806401000000008110610e8b57600080fd5b610e958284611af0565b505050565b600254604080517f172a735c000000000000000000000000000000000000000000000000000000008152600481018490529051600160a060020a039092169163172a735c916024808201926020929091908290030181600087803b158015610f0157600080fd5b505af1158015610f15573d6000803e3d6000fd5b505050506040513d6020811015610e9557600080fd5b600354600160a060020a031633148015610fcb5750600160009054906101000a9004600160a060020a0316600160a060020a0316638da5cb5b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015610f9357600080fd5b505af1158015610fa7573d6000803e3d6000fd5b505050506040513d6020811015610fbd57600080fd5b5051600160a060020a031630145b801561105d5750600260009054906101000a9004600160a060020a0316600160a060020a0316638da5cb5b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561102557600080fd5b505af1158015611039573d6000803e3d6000fd5b505050506040513d602081101561104f57600080fd5b5051600160a060020a031630145b151561106857600080fd5b565b7f01ffc9a70000000000000000000000000000000000000000000000000000000081565b600154604080517f728aa85700000000000000000000000000000000000000000000000000000000815263ffffffff861660048201523360248201529051600092600160a060020a03169163728aa85791604480830192602092919082900301818787803b1580156110ff57600080fd5b505af1158015611113573d6000803e3d6000fd5b505050506040513d602081101561112957600080fd5b5051151561113657600080fd5b6001546040805160e060020a635e19b30502815263ffffffff871660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b15801561118c57600080fd5b505af11580156111a0573d6000803e3d6000fd5b505050506040513d60208110156111b657600080fd5b5051151561124257600154604080517f7bc702a100000000000000000000000000000000000000000000000000000000815263ffffffff871660048201529051600160a060020a0390921691637bc702a19160248082019260009290919082900301818387803b15801561122957600080fd5b505af115801561123d573d6000803e3d6000fd5b505050505b6001546040805160e060020a63caf590f902815263ffffffff87166004820152600160a060020a0386811660248301529151919092169163caf590f99160448083019260209291908290030181600087803b1580156112a057600080fd5b505af11580156112b4573d6000803e3d6000fd5b505050506040513d60208110156112ca57600080fd5b5051151561149b576001546040805160e160020a63310d91f102815263ffffffff871660048201529051600160a060020a039092169163621b23e2916024808201926020929091908290030181600087803b15801561132857600080fd5b505af115801561133c573d6000803e3d6000fd5b505050506040513d602081101561135257600080fd5b5051600154604080517fddc3595000000000000000000000000000000000000000000000000000000000815263ffffffff88166004820152600160a060020a038781166024830152915193945091169163ddc359509160448082019260009290919082900301818387803b1580156113c957600080fd5b505af11580156113dd573d6000803e3d6000fd5b50506001546040805160e260020a630b1ee95902815263ffffffff891660048201526000602482018190529151600160a060020a039093169450632c7ba56493506044808201939182900301818387803b15801561143a57600080fd5b505af115801561144e573d6000803e3d6000fd5b50506040805163ffffffff881681529051600160a060020a038088169450851692507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35b81156118cd576001546040805160e060020a636d09887b02815263ffffffff871660048201529051600160a060020a0390921691636d09887b916024808201926020929091908290030181600087803b1580156114f757600080fd5b505af115801561150b573d6000803e3d6000fd5b505050506040513d602081101561152157600080fd5b50511561164157600154604080517ff491491900000000000000000000000000000000000000000000000000000000815263ffffffff871660048201529051600160a060020a039092169163f49149199160248082019260009290919082900301818387803b15801561159357600080fd5b505af11580156115a7573d6000803e3d6000fd5b5050600154604080517ff9b87d4000000000000000000000000000000000000000000000000000000000815263ffffffff8916600482015260006024820181905260448201819052606482018190529151600160a060020a03909316945063f9b87d4093506084808201939182900301818387803b15801561162857600080fd5b505af115801561163c573d6000803e3d6000fd5b505050505b600154604080517f8866bb2c00000000000000000000000000000000000000000000000000000000815263ffffffff871660048201526000602482018190529151600160a060020a0390931692638866bb2c9260448084019391929182900301818387803b1580156116b257600080fd5b505af11580156116c6573d6000803e3d6000fd5b5050600154604080517fa297c1d800000000000000000000000000000000000000000000000000000000815263ffffffff891660048201526000602482018190529151600160a060020a03909316945063a297c1d893506044808201939182900301818387803b15801561173957600080fd5b505af115801561174d573d6000803e3d6000fd5b50506001546040805160e260020a630b1ee95902815263ffffffff891660048201526000602482018190529151600160a060020a039093169450632c7ba56493506044808201939182900301818387803b1580156117aa57600080fd5b505af11580156117be573d6000803e3d6000fd5b5050600154604080517f2a19642c00000000000000000000000000000000000000000000000000000000815263ffffffff891660048201526000602482018190529151600160a060020a039093169450632a19642c93506044808201939182900301818387803b15801561183157600080fd5b505af1158015611845573d6000803e3d6000fd5b5050600554604080517feaae46e500000000000000000000000000000000000000000000000000000000815263ffffffff891660048201529051600160a060020a03909216935063eaae46e5925060248082019260009290919082900301818387803b1580156118b457600080fd5b505af11580156118c8573d6000803e3d6000fd5b505050505b50505050565b60008164010000000081106118e757600080fd5b6001546040805160e060020a63caf590f902815263ffffffff86166004820152600160a060020a0388811660248301529151869550919092169163caf590f99160448083019260209291908290030181600087803b15801561194857600080fd5b505af115801561195c573d6000803e3d6000fd5b505050506040513d602081101561197257600080fd5b5051151561197f57600080fd5b610d328285600161108e565b600054600160a060020a031633146119a257600080fd5b6001546040805160e060020a63caf590f902815260ff851660048201526000602482018190529151600160a060020a039093169263caf590f992604480840193602093929083900390910190829087803b1580156119ff57600080fd5b505af1158015611a13573d6000803e3d6000fd5b505050506040513d6020811015611a2957600080fd5b50518015611a3f5750600160a060020a03811615155b1515611a4a57600080fd5b600260009054906101000a9004600160a060020a0316600160a060020a031663246d41a96040518163ffffffff1660e060020a028152600401600060405180830381600087803b158015611a9d57600080fd5b505af1158015611ab1573d6000803e3d6000fd5b50505050600160a060020a038116331415611adc57611ad78260ff168260016000614426565b611aec565b611aec8260ff1682600033614426565b5050565b6001546040805160e160020a63310d91f102815263ffffffff851660048201529051600092600160a060020a03169163621b23e291602480830192602092919082900301818787803b158015611b4557600080fd5b505af1158015611b59573d6000803e3d6000fd5b505050506040513d6020811015611b6f57600080fd5b50519050600160a060020a038116331480611c205750600154604080517fb6363cf2000000000000000000000000000000000000000000000000000000008152600160a060020a0384811660048301523360248301529151919092169163b6363cf29160448083019260209291908290030181600087803b158015611bf357600080fd5b505af1158015611c07573d6000803e3d6000fd5b505050506040513d6020811015611c1d57600080fd5b50515b1515611c2b57600080fd5b6001546040805160e260020a630b1ee95902815263ffffffff86166004820152600160a060020a03858116602483015291519190921691632c7ba56491604480830192600092919082900301818387803b158015611c8857600080fd5b505af1158015611c9c573d6000803e3d6000fd5b50506040805163ffffffff871681529051600160a060020a038087169450851692507f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360200190a3505050565b610e9583838360206040519081016040528060008152506135b1565b600154604080517f9137fe0a00000000000000000000000000000000000000000000000000000000815263ffffffff8816600482015233602482015290518792600160a060020a031691639137fe0a9160448083019260209291908290030181600087803b158015611d7a57600080fd5b505af1158015611d8e573d6000803e3d6000fd5b505050506040513d6020811015611da457600080fd5b50518015611e3057506001546040805160e060020a635e19b30502815263ffffffff841660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b158015611e0357600080fd5b505af1158015611e17573d6000803e3d6000fd5b505050506040513d6020811015611e2d57600080fd5b50515b1515611e3b57600080fd5b8115611ec557600154604080517ff491491900000000000000000000000000000000000000000000000000000000815263ffffffff891660048201529051600160a060020a039092169163f49149199160248082019260009290919082900301818387803b158015611eac57600080fd5b505af1158015611ec0573d6000803e3d6000fd5b505050505b600154604080517ff9b87d4000000000000000000000000000000000000000000000000000000000815263ffffffff808a1660048301526024820189905260448201889052861660648201529051600160a060020a039092169163f9b87d409160848082019260009290919082900301818387803b158015611f4657600080fd5b505af1158015611f5a573d6000803e3d6000fd5b50505050505050505050565b6001546040805160e060020a636d09887b02815263ffffffff84166004820152905160009283928392600160a060020a0390921691636d09887b9160248082019260209290919082900301818787803b158015611fc257600080fd5b505af1158015611fd6573d6000803e3d6000fd5b505050506040513d6020811015611fec57600080fd5b50511515611ffd57600092506121d5565b6001546040805160e060020a639397640502815263ffffffff881660048201529051600160a060020a03909216916393976405916024808201926020929091908290030181600087803b15801561205357600080fd5b505af1158015612067573d6000803e3d6000fd5b505050506040513d602081101561207d57600080fd5b50516001546040805160e060020a639397640502815263ffffffff881660048201529051929450600160a060020a03909116916393976405916024808201926020929091908290030181600087803b1580156120d857600080fd5b505af11580156120ec573d6000803e3d6000fd5b505050506040513d602081101561210257600080fd5b5051905081600281111561211257fe5b60ff1681600281111561212157fe5b60010160ff1614806121d2575081600281111561213a57fe5b81600281111561214657fe5b1480156121d257506001546040805160e060020a636d09887b02815263ffffffff881660048201529051600160a060020a0390921691636d09887b916024808201926020929091908290030181600087803b1580156121a457600080fd5b505af11580156121b8573d6000803e3d6000fd5b505050506040513d60208110156121ce57600080fd5b5051155b92505b505092915050565b60006401000000008210801561227157506001546040805160e060020a635e19b30502815263ffffffff851660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b15801561224457600080fd5b505af1158015612258573d6000803e3d6000fd5b505050506040513d602081101561226e57600080fd5b50515b92915050565b6001546040805160e060020a63b65afedd02815260ff8616600482018190523360248301529151600093600160a060020a03169163b65afedd91604480830192602092919082900301818887803b1580156122d157600080fd5b505af11580156122e5573d6000803e3d6000fd5b505050506040513d60208110156122fb57600080fd5b5051801561238757506001546040805160e060020a635e19b30502815263ffffffff841660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b15801561235a57600080fd5b505af115801561236e573d6000803e3d6000fd5b505050506040513d602081101561238457600080fd5b50515b151561239257600080fd5b600254604080517f51de554100000000000000000000000000000000000000000000000000000000815260ff88166004820152600160a060020a0387811660248301528615156044830152915191909216916351de55419160648083019260209291908290030181600087803b15801561240b57600080fd5b505af115801561241f573d6000803e3d6000fd5b505050506040513d602081101561243557600080fd5b505191508115610d3257610d32846147a7565b600254604080517f5623715b000000000000000000000000000000000000000000000000000000008152600160a060020a03848116600483015291516000939290921691635623715b9160248082019260209290919082900301818787803b1580156124b357600080fd5b505af11580156124c7573d6000803e3d6000fd5b505050506040513d60208110156124dd57600080fd5b505190508015611aec57611aec826147a7565b60008082640100000000811061250557600080fd5b6001546040805160e060020a635e19b30502815263ffffffff871660048201529051869450600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b15801561255e57600080fd5b505af1158015612572573d6000803e3d6000fd5b505050506040513d602081101561258857600080fd5b5051151561259557600080fd5b6001546040805160e160020a63310d91f102815263ffffffff851660048201529051600160a060020a039092169163621b23e2916024808201926020929091908290030181600087803b1580156125eb57600080fd5b505af11580156125ff573d6000803e3d6000fd5b505050506040513d602081101561261557600080fd5b5051949350505050565b6001546040805160e060020a63b65afedd02815260ff86166004820181905233602483015291519192600160a060020a03169163b65afedd916044808201926020929091908290030181600087803b15801561267a57600080fd5b505af115801561268e573d6000803e3d6000fd5b505050506040513d60208110156126a457600080fd5b5051801561273057506001546040805160e060020a635e19b30502815263ffffffff841660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b15801561270357600080fd5b505af1158015612717573d6000803e3d6000fd5b505050506040513d602081101561272d57600080fd5b50515b151561273b57600080fd5b600254604080517f6eb5822400000000000000000000000000000000000000000000000000000000815260ff871660048201526024810186905284151560448201529051600160a060020a0390921691636eb58224916064808201926020929091908290030181600087803b1580156127b357600080fd5b505af11580156127c7573d6000803e3d6000fd5b505050506040513d60208110156127dd57600080fd5b505050505050565b6000600160a060020a03821615156127fc57600080fd5b600154604080517f12afbc78000000000000000000000000000000000000000000000000000000008152600160a060020a038581166004830152915191909216916312afbc789160248083019260209291908290030181600087803b15801561224457600080fd5b600054600160a060020a0316331461287b57600080fd5b60008054604051600160a060020a03909116917ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482091a26000805473ffffffffffffffffffffffffffffffffffffffff19169055565b6001546040805160e060020a63caf590f902815263ffffffff8516600482015233602482015290518492600160a060020a03169163caf590f99160448083019260209291908290030181600087803b15801561292b57600080fd5b505af115801561293f573d6000803e3d6000fd5b505050506040513d602081101561295557600080fd5b505180156129e157506001546040805160e060020a635e19b30502815263ffffffff841660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b1580156129b457600080fd5b505af11580156129c8573d6000803e3d6000fd5b505050506040513d60208110156129de57600080fd5b50515b15156129ec57600080fd5b600154604080517f8866bb2c00000000000000000000000000000000000000000000000000000000815263ffffffff86166004820152600160a060020a03858116602483015291519190921691638866bb2c91604480830192600092919082900301818387803b158015610aa457600080fd5b600054600160a060020a031681565b60408051808201909152600381527f415a500000000000000000000000000000000000000000000000000000000000602082015290565b6001546040805160e060020a63b65afedd02815260ff85166004820181905233602483015291519192600160a060020a03169163b65afedd916044808201926020929091908290030181600087803b158015612b0057600080fd5b505af1158015612b14573d6000803e3d6000fd5b505050506040513d6020811015612b2a57600080fd5b50518015612bb657506001546040805160e060020a635e19b30502815263ffffffff841660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b158015612b8957600080fd5b505af1158015612b9d573d6000803e3d6000fd5b505050506040513d6020811015612bb357600080fd5b50515b1515612bc157600080fd5b30600160a060020a031682600160a060020a031663ed969f686040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015612c0957600080fd5b505af1158015612c1d573d6000803e3d6000fd5b505050506040513d6020811015612c3357600080fd5b5051600160a060020a031614612c4857600080fd5b600254604080517fe31f3e0c000000000000000000000000000000000000000000000000000000008152600160a060020a0385811660048301529151919092169163e31f3e0c91602480830192600092919082900301818387803b158015610aa457600080fd5b6001546040805160e060020a63caf590f902815263ffffffff8516600482015260006024820181905291519192600160a060020a03169163caf590f99160448082019260209290919082900301818787803b158015612d0d57600080fd5b505af1158015612d21573d6000803e3d6000fd5b505050506040513d6020811015612d3757600080fd5b50511515612d4457600080fd5b600154604080517fe4a358d700000000000000000000000000000000000000000000000000000000815263ffffffff861660048201529051600160a060020a039092169163e4a358d7916024808201926020929091908290030181600087803b158015612db057600080fd5b505af1158015612dc4573d6000803e3d6000fd5b505050506040513d6020811015612dda57600080fd5b50516001546040805160e060020a639397640502815263ffffffff871660048201529051929350600160a060020a03909116916393976405916024808201926020929091908290030181600087803b158015612e3557600080fd5b505af1158015612e49573d6000803e3d6000fd5b505050506040513d6020811015612e5f57600080fd5b50516002811115612e6c57fe5b6001546040805160e060020a639397640502815261ffff85166004820152905160ff9390931692600160a060020a03909216916393976405916024808201926020929091908290030181600087803b158015612ec757600080fd5b505af1158015612edb573d6000803e3d6000fd5b505050506040513d6020811015612ef157600080fd5b50516002811115612efe57fe5b60010160ff16141515612f1057600080fd5b6001546040805160e060020a636d09887b02815261ffff841660048201529051600160a060020a0390921691636d09887b916024808201926020929091908290030181600087803b158015612f6457600080fd5b505af1158015612f78573d6000803e3d6000fd5b505050506040513d6020811015612f8e57600080fd5b5051801561304d5750612fa58161ffff164261430d565b600154604080517f293a916900000000000000000000000000000000000000000000000000000000815261ffff85166004820152905163ffffffff9390931692600160a060020a039092169163293a9169916024808201926020929091908290030181600087803b15801561301957600080fd5b505af115801561302d573d6000803e3d6000fd5b505050506040513d602081101561304357600080fd5b505163ffffffff16105b151561305857600080fd5b600154604080517f8a27bf5900000000000000000000000000000000000000000000000000000000815261ffff841660048201523360248201529051600160a060020a0390921691638a27bf59916044808201926020929091908290030181600087803b1580156130c857600080fd5b505af11580156130dc573d6000803e3d6000fd5b505050506040513d60208110156130f257600080fd5b505115156130ff57600080fd5b33600160a060020a03831614156131235761311e838360016000614426565b610e95565b6001546040805160e160020a63310d91f102815261ffff841660048201529051610e959286928692600092600160a060020a03169163621b23e291602480830192602092919082900301818787803b15801561317e57600080fd5b505af1158015613192573d6000803e3d6000fd5b505050506040513d60208110156131a857600080fd5b5051614426565b600160a060020a03821615156131c457600080fd5b600154604080517fbc735d90000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a03858116602483015284151560448301529151919092169163bc735d9091606480830192600092919082900301818387803b15801561323957600080fd5b505af115801561324d573d6000803e3d6000fd5b50506040805184151581529051600160a060020a03861693503392507f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c319181900360200190a35050565b6001546040805160e060020a63caf590f902815260ff85166004820181905233602483015291519192600160a060020a03169163caf590f9916044808201926020929091908290030181600087803b1580156132f257600080fd5b505af1158015613306573d6000803e3d6000fd5b505050506040513d602081101561331c57600080fd5b505180156133a857506001546040805160e060020a635e19b30502815263ffffffff841660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b15801561337b57600080fd5b505af115801561338f573d6000803e3d6000fd5b505050506040513d60208110156133a557600080fd5b50515b15156133b357600080fd5b600154604080517fa297c1d800000000000000000000000000000000000000000000000000000000815260ff86166004820152600160a060020a0385811660248301529151919092169163a297c1d891604480830192600092919082900301818387803b158015610aa457600080fd5b6001546040805160e060020a63caf590f902815261ffff85166004820181905233602483015291519192600160a060020a03169163caf590f9916044808201926020929091908290030181600087803b15801561347f57600080fd5b505af1158015613493573d6000803e3d6000fd5b505050506040513d60208110156134a957600080fd5b5051801561353557506001546040805160e060020a635e19b30502815263ffffffff841660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b15801561350857600080fd5b505af115801561351c573d6000803e3d6000fd5b505050506040513d602081101561353257600080fd5b50515b151561354057600080fd5b600154604080517f2a19642c00000000000000000000000000000000000000000000000000000000815261ffff86166004820152600160a060020a03858116602483015291519190921691632a19642c91604480830192600092919082900301818387803b158015610aa457600080fd5b60006135be8585856118d3565b6135d084600160a060020a0316614944565b15610d32576040517f150b7a020000000000000000000000000000000000000000000000000000000081523360048201818152600160a060020a038881166024850152604484018790526080606485019081528651608486015286519189169463150b7a0294938b938a938a93909160a490910190602085019080838360005b83811015613668578181015183820152602001613650565b50505050905090810190601f1680156136955780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b1580156136b757600080fd5b505af11580156136cb573d6000803e3d6000fd5b505050506040513d60208110156136e157600080fd5b50519050600160e060020a031981167f150b7a020000000000000000000000000000000000000000000000000000000014610d3257600080fd5b600054600160a060020a0316331461373257600080fd5b6001546040517fbac55edd00000000000000000000000000000000000000000000000000000000815260606004820190815260648201889052600160a060020a039092169163bac55edd918991899189918991899189918190602481019060448101906084018a8a80828437909101858103845288815260200190508888808284379091018581038352868152602001905086868082843782019150509950505050505050505050600060405180830381600087803b158015611f4657600080fd5b600154604080517f9b350e1200000000000000000000000000000000000000000000000000000000815263ffffffff841660048201529051600160a060020a0390921691639b350e12916024808201926020929091908290030181600087803b15801561386057600080fd5b505af1158015613874573d6000803e3d6000fd5b505050506040513d602081101561388a57600080fd5b505180156139a45750600154604080517ff5af662100000000000000000000000000000000000000000000000000000000815263ffffffff841660048201529051600160a060020a0390921691639137fe0a91839163f5af6621916024808201926020929091908290030181600087803b15801561390757600080fd5b505af115801561391b573d6000803e3d6000fd5b505050506040513d602081101561393157600080fd5b50516040805163ffffffff84811660e060020a02825290921660048301523360248301525160448083019260209291908290030181600087803b15801561397757600080fd5b505af115801561398b573d6000803e3d6000fd5b505050506040513d60208110156139a157600080fd5b50515b15156139af57600080fd5b600154604080517fc6d761d400000000000000000000000000000000000000000000000000000000815263ffffffff841660048201529051600160a060020a039092169163c6d761d49160248082019260009290919082900301818387803b158015610d1e57600080fd5b600154604080517f9137fe0a00000000000000000000000000000000000000000000000000000000815263ffffffff8516600482015233602482015290518492600160a060020a031691639137fe0a9160448083019260209291908290030181600087803b158015613a8b57600080fd5b505af1158015613a9f573d6000803e3d6000fd5b505050506040513d6020811015613ab557600080fd5b50518015613b4157506001546040805160e060020a635e19b30502815263ffffffff841660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b158015613b1457600080fd5b505af1158015613b28573d6000803e3d6000fd5b505050506040513d6020811015613b3e57600080fd5b50515b1515613b4c57600080fd5b613b568383611f66565b1515613b6157600080fd5b600154604080517fa634585900000000000000000000000000000000000000000000000000000000815263ffffffff8087166004830152851660248201529051600160a060020a039092169163a63458599160448082019260009290919082900301818387803b158015610aa457600080fd5b600154604080517f9b350e1200000000000000000000000000000000000000000000000000000000815263ffffffff841660048201529051600160a060020a0390921691639b350e12916024808201926020929091908290030181600087803b158015613c4057600080fd5b505af1158015613c54573d6000803e3d6000fd5b505050506040513d6020811015613c6a57600080fd5b50518015613d845750600154604080517ff5af662100000000000000000000000000000000000000000000000000000000815263ffffffff841660048201529051600160a060020a0390921691639137fe0a91839163f5af6621916024808201926020929091908290030181600087803b158015613ce757600080fd5b505af1158015613cfb573d6000803e3d6000fd5b505050506040513d6020811015613d1157600080fd5b50516040805163ffffffff84811660e060020a02825290921660048301523360248301525160448083019260209291908290030181600087803b158015613d5757600080fd5b505af1158015613d6b573d6000803e3d6000fd5b505050506040513d6020811015613d8157600080fd5b50515b1515613d8f57600080fd5b600154604080517f1306318000000000000000000000000000000000000000000000000000000000815263ffffffff841660048201529051600160a060020a039092169163130631809160248082019260009290919082900301818387803b158015610d1e57600080fd5b600154604080517f9137fe0a00000000000000000000000000000000000000000000000000000000815263ffffffff8416600482015233602482015290518392600160a060020a031691639137fe0a9160448083019260209291908290030181600087803b158015613e6b57600080fd5b505af1158015613e7f573d6000803e3d6000fd5b505050506040513d6020811015613e9557600080fd5b50518015613f2157506001546040805160e060020a635e19b30502815263ffffffff841660048201529051600160a060020a0390921691635e19b305916024808201926020929091908290030181600087803b158015613ef457600080fd5b505af1158015613f08573d6000803e3d6000fd5b505050506040513d6020811015613f1e57600080fd5b50515b1515613f2c57600080fd5b600154604080517fc6d761d400000000000000000000000000000000000000000000000000000000815263ffffffff851660048201529051600160a060020a039092169163c6d761d49160248082019260009290919082900301818387803b158015613f9757600080fd5b505af11580156127dd573d6000803e3d6000fd5b606080826401000000008110613fc057600080fd5b60408051606081018252602e81527f68747470733a2f2f617a696d7574682e6e6574776f726b2f6572633732312f3060208201527f3030303030303030302e6a736f6e0000000000000000000000000000000000009181019190915292508291507fff00000000000000000000000000000000000000000000000000000000000000600a633b9aca0086040660300160f860020a0216600081901a603f84015350600a6305f5e10085040660300160f860020a0282602081518110151561408357fe5b906020010190600160f860020a031916908160001a905350600a6298968085040660300160f860020a028260218151811015156140bc57fe5b906020010190600160f860020a031916908160001a905350600a620f424085040660300160f860020a028260228151811015156140f557fe5b906020010190600160f860020a031916908160001a905350600a620186a085040660300160f860020a0282602381518110151561412e57fe5b906020010190600160f860020a031916908160001a905350600a61271085040660300160f860020a0282602481518110151561416657fe5b906020010190600160f860020a031916908160001a905350600a6103e885040660300160f860020a0282602581518110151561419e57fe5b906020010190600160f860020a031916908160001a905350600a606485040660300160f860020a028260268151811015156141d557fe5b906020010190600160f860020a031916908160001a905350600a8085040660300160f860020a0282602781518110151561420b57fe5b906020010190600160f860020a031916908160001a905350600a840660300160f860020a0282602881518110151561423f57fe5b906020010190600160f860020a031916908160001a9053505050919050565b600154600160a060020a031681565b600554600160a060020a031681565b600254600160a060020a031681565b600154604080517fb6363cf2000000000000000000000000000000000000000000000000000000008152600160a060020a03858116600483015284811660248301529151600093929092169163b6363cf29160448082019260209290919082900301818787803b158015610e4657600080fd5b600354600160a060020a031681565b6001546040805160e060020a639397640502815263ffffffff85166004820152905160009283928392600160a060020a039092169163939764059160248082019260209290919082900301818787803b15801561436957600080fd5b505af115801561437d573d6000803e3d6000fd5b505050506040513d602081101561439357600080fd5b5051915060008260028111156143a557fe5b14156143b45760ff92506121d5565b60018260028111156143c257fe5b14156143fa57506301e13380635c2aad7f1984010460068110156143ef578060020a6104000292506143f5565b61ffff92505b6121d5565b600092506121d5565b600054600160a060020a0316331461441a57600080fd5b6144238161494c565b50565b600154604080517fc17ad9d800000000000000000000000000000000000000000000000000000000815263ffffffff871660048201529051600160a060020a039092169163c17ad9d89160248082019260009290919082900301818387803b15801561449157600080fd5b505af11580156144a5573d6000803e3d6000fd5b50505050811561460957600154604080517f7bc702a100000000000000000000000000000000000000000000000000000000815263ffffffff871660048201529051600160a060020a0390921691637bc702a19160248082019260009290919082900301818387803b15801561451a57600080fd5b505af115801561452e573d6000803e3d6000fd5b5050600154604080517fddc3595000000000000000000000000000000000000000000000000000000000815263ffffffff89166004820152600160a060020a038881166024830152915191909216935063ddc359509250604480830192600092919082900301818387803b1580156145a557600080fd5b505af11580156145b9573d6000803e3d6000fd5b50506040805163ffffffff881681529051600160a060020a0387169350600092507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a36118cd565b600154604080517fddc3595000000000000000000000000000000000000000000000000000000000815263ffffffff87166004820152600160a060020a0384811660248301529151919092169163ddc3595091604480830192600092919082900301818387803b15801561467c57600080fd5b505af1158015614690573d6000803e3d6000fd5b50506001546040805160e260020a630b1ee95902815263ffffffff89166004820152600160a060020a0388811660248301529151919092169350632c7ba5649250604480830192600092919082900301818387803b1580156146f157600080fd5b505af1158015614705573d6000803e3d6000fd5b50506040805163ffffffff881681529051600160a060020a0385169350600092507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a382600160a060020a031681600160a060020a03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258663ffffffff166040518082815260200191505060405180910390a350505050565b600154604080517ff2fde38b000000000000000000000000000000000000000000000000000000008152600160a060020a0384811660048301529151919092169163f2fde38b91602480830192600092919082900301818387803b15801561480e57600080fd5b505af1158015614822573d6000803e3d6000fd5b5050600254604080517ff2fde38b000000000000000000000000000000000000000000000000000000008152600160a060020a038681166004830152915191909216935063f2fde38b9250602480830192600092919082900301818387803b15801561488d57600080fd5b505af11580156148a1573d6000803e3d6000fd5b5050505080600160a060020a0316631824a46b6040518163ffffffff1660e060020a028152600401600060405180830381600087803b1580156148e357600080fd5b505af11580156148f7573d6000803e3d6000fd5b505060408051600160a060020a038516815290517fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9350908190036020019150a180600160a060020a0316ff5b6000903b1190565b600160a060020a038116151561496157600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03929092169190911790555600a165627a7a7230582053db0352084252f483a76437bf131ec08201d58fe878f89b3bffa84a3e6d3dad0029
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000a23b5d8e86091ab6c14981f404c2864701aa2903000000000000000000000000223c067f8cf28ae173ee5cafea60ca44c335fecb0000000000000000000000007fecab617c868bb5996d99d95200d2fa708218e4000000000000000000000000e7e7f69b34d7d9bd8d61fb22c33b22708947971a
-----Decoded View---------------
Arg [0] : _previous (address): 0xa23B5d8e86091aB6c14981F404c2864701aa2903
Arg [1] : _azimuth (address): 0x223c067F8CF28ae173EE5CafEa60cA44C335fecB
Arg [2] : _polls (address): 0x7fEcaB617c868Bb5996d99D95200D2Fa708218e4
Arg [3] : _claims (address): 0xe7e7f69b34D7d9Bd8d61Fb22C33b22708947971A
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000a23b5d8e86091ab6c14981f404c2864701aa2903
Arg [1] : 000000000000000000000000223c067f8cf28ae173ee5cafea60ca44c335fecb
Arg [2] : 0000000000000000000000007fecab617c868bb5996d99d95200d2fa708218e4
Arg [3] : 000000000000000000000000e7e7f69b34d7d9bd8d61fb22c33b22708947971a
Swarm Source
bzzr://53db0352084252f483a76437bf131ec08201d58fe878f89b3bffa84a3e6d3dad
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.