Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Transactions Sent
Latest:
N/A
First:
N/A
Latest 25 from a total of 32,008 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Spawn | 20453299 | 29 days ago | IN | 0 ETH | 0.0000216 | ||||
Configure Keys | 20453213 | 29 days ago | IN | 0 ETH | 0.00002253 | ||||
Configure Keys | 20452954 | 30 days ago | IN | 0 ETH | 0.00002253 | ||||
Configure Keys | 20451703 | 30 days ago | IN | 0 ETH | 0.00002252 | ||||
Configure Keys | 20409075 | 36 days ago | IN | 0 ETH | 0.00002252 | ||||
Configure Keys | 20409026 | 36 days ago | IN | 0 ETH | 0.00002252 | ||||
Configure Keys | 20408456 | 36 days ago | IN | 0 ETH | 0.00002252 | ||||
Configure Keys | 20176654 | 68 days ago | IN | 0 ETH | 0.00367271 | ||||
Set Approval For... | 17987623 | 375 days ago | IN | 0 ETH | 0.00047153 | ||||
Set Approval For... | 17807325 | 400 days ago | IN | 0 ETH | 0.00046383 | ||||
Set Approval For... | 17807317 | 400 days ago | IN | 0 ETH | 0.00047852 | ||||
Configure Keys | 16277482 | 615 days ago | IN | 0 ETH | 0.0004957 | ||||
Configure Keys | 15383310 | 743 days ago | IN | 0 ETH | 0.00004506 | ||||
Approve | 14247611 | 925 days ago | IN | 0 ETH | 0.00144824 | ||||
Approve | 14247600 | 925 days ago | IN | 0 ETH | 0.00151403 | ||||
Transfer Point | 13456907 | 1048 days ago | IN | 0 ETH | 0.00153542 | ||||
Start Upgrade Po... | 13052474 | 1111 days ago | IN | 0 ETH | 0.00064716 | ||||
Transfer Point | 12968251 | 1124 days ago | IN | 0 ETH | 0.00086944 | ||||
Transfer Point | 12967914 | 1124 days ago | IN | 0 ETH | 0.00119548 | ||||
Transfer Point | 12967520 | 1124 days ago | IN | 0 ETH | 0.0010439 | ||||
Transfer Point | 12966861 | 1124 days ago | IN | 0 ETH | 0.0010874 | ||||
Transfer Point | 12964183 | 1124 days ago | IN | 0 ETH | 0.00078292 | ||||
Transfer Point | 12937625 | 1129 days ago | IN | 0 ETH | 0.0010874 | ||||
Transfer Point | 12937625 | 1129 days ago | IN | 0 ETH | 0.0010874 | ||||
Transfer Point | 12937625 | 1129 days ago | IN | 0 ETH | 0.00130488 |
Advanced mode: Intended for advanced users or developers and will display all Internal Transactions including zero value transfers. Name tag integration is not available in advanced view.
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | ||||
---|---|---|---|---|---|---|---|
14738755 | 848 days ago | 0 ETH | |||||
12742785 | 1159 days ago | 0 ETH | |||||
12685757 | 1168 days ago | 0 ETH | |||||
12685757 | 1168 days ago | 0 ETH | |||||
12685757 | 1168 days ago | 0 ETH | |||||
12685757 | 1168 days ago | 0 ETH | |||||
12685757 | 1168 days ago | 0 ETH | |||||
12685414 | 1168 days ago | 0 ETH | |||||
12685414 | 1168 days ago | 0 ETH | |||||
12685414 | 1168 days ago | 0 ETH | |||||
12685414 | 1168 days ago | 0 ETH | |||||
12685414 | 1168 days ago | 0 ETH | |||||
12685414 | 1168 days ago | 0 ETH | |||||
12685414 | 1168 days ago | 0 ETH | |||||
12685414 | 1168 days ago | 0 ETH | |||||
12685414 | 1168 days ago | 0 ETH | |||||
12685414 | 1168 days ago | 0 ETH | |||||
12685414 | 1168 days ago | 0 ETH | |||||
12685414 | 1168 days ago | 0 ETH | |||||
12685414 | 1168 days ago | 0 ETH | |||||
12685414 | 1168 days ago | 0 ETH | |||||
12684676 | 1168 days ago | 0 ETH | |||||
12684676 | 1168 days ago | 0 ETH | |||||
12684676 | 1168 days ago | 0 ETH | |||||
12684676 | 1168 days ago | 0 ETH |
Loading...
Loading
Contract Self Destruct called at Txn Hash 0x4603b815fc577fd0b61ba16ad7b091421ace227962e7c4ff563d26e073c1b739
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
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.