Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- ProxyStorage
- Optimization enabled
- true
- Compiler version
- v0.4.26+commit.4563c3fc
- Optimization runs
- 200
- EVM Version
- default
- Verified at
- 2025-04-01T07:08:19.492183Z
Contract source code
// File: contracts/eternal-storage/EternalStorage.sol pragma solidity ^0.4.24; /** * @title EternalStorage * @author LiorRabin * @dev This contract holds all the necessary state variables to carry out the storage of any contract and to support the upgrade functionality. */ contract EternalStorage { // Version number of the current implementation uint256 internal version; // Address of the current implementation address internal implementation; // Storage mappings mapping(bytes32 => uint256) internal uintStorage; mapping(bytes32 => string) internal stringStorage; mapping(bytes32 => address) internal addressStorage; mapping(bytes32 => bytes) internal bytesStorage; mapping(bytes32 => bool) internal boolStorage; mapping(bytes32 => int256) internal intStorage; mapping(bytes32 => uint256[]) internal uintArrayStorage; mapping(bytes32 => string[]) internal stringArrayStorage; mapping(bytes32 => address[]) internal addressArrayStorage; mapping(bytes32 => bytes[]) internal bytesArrayStorage; mapping(bytes32 => bool[]) internal boolArrayStorage; mapping(bytes32 => int256[]) internal intArrayStorage; mapping(bytes32 => bytes32[]) internal bytes32ArrayStorage; function isInitialized() public view returns(bool) { return boolStorage[keccak256(abi.encodePacked("isInitialized"))]; } function setInitialized(bool _status) internal { boolStorage[keccak256(abi.encodePacked("isInitialized"))] = _status; } } // File: contracts/eternal-storage/EternalStorageProxy.sol pragma solidity ^0.4.24; /** * @title EternalStorageProxy * @author LiorRabin * @dev This proxy holds the storage of the token contract and delegates every call to the current implementation set. * Besides, it allows to upgrade the token's behaviour towards further implementations, and provides authorization control functionalities */ contract EternalStorageProxy is EternalStorage { /** * @dev This event will be emitted every time the implementation gets upgraded * @param version representing the version number of the upgraded implementation * @param implementation representing the address of the upgraded implementation */ event Upgraded(uint256 version, address indexed implementation); /** * @dev This event will be emitted when ownership is renounces * @param previousOwner address which is renounced from ownership */ event OwnershipRenounced(address indexed previousOwner); /** * @dev This event will be emitted when ownership is transferred * @param previousOwner address which represents the previous owner * @param newOwner address which represents the new owner */ event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev This modifier verifies that msg.sender is the ProxyStorage contract */ modifier onlyProxyStorage() { require(msg.sender == getProxyStorage()); _; } /** * @dev This modifier verifies that msg.sender is the owner of the contract */ modifier onlyOwner() { require(msg.sender == getOwner()); _; } /** * @dev Constructor * @param _proxyStorage address representing the ProxyStorage contract * @param _implementation address representing the implementation contract */ constructor(address _proxyStorage, address _implementation) public { require(_implementation != address(0)); if (_proxyStorage != address(0)) { _setProxyStorage(_proxyStorage); } else { _setProxyStorage(address(this)); } _setImplementation(_implementation); _setOwner(msg.sender); } /** * @dev Fallback function allowing to perform a delegatecall to the given implementation. * This function will return whatever the implementation call returns */ // solhint-disable no-complex-fallback, no-inline-assembly function() payable public { address _impl = getImplementation(); require(_impl != address(0)); assembly { // Copy msg.data. We take full control of memory in this inline assembly // block because it will not return to Solidity code. We overwrite the // Solidity scratch pad at memory position 0 calldatacopy(0, 0, calldatasize) // Call the implementation. // out and outsize are 0 because we don't know the size yet let result := delegatecall(gas, _impl, 0, calldatasize, 0, 0) // Copy the returned data returndatacopy(0, 0, returndatasize) switch result // delegatecall returns 0 on error case 0 { revert(0, returndatasize) } default { return(0, returndatasize) } } } // solhint-enable no-complex-fallback, no-inline-assembly /** * @dev Allows ProxyStorage contract (only) to upgrade the current implementation. * @param _newImplementation representing the address of the new implementation to be set. */ function upgradeTo(address _newImplementation) public onlyProxyStorage returns(bool) { if (_newImplementation == address(0)) return false; if (getImplementation() == _newImplementation) return false; uint256 _newVersion = getVersion() + 1; _setVersion(_newVersion); _setImplementation(_newImplementation); emit Upgraded(_newVersion, _newImplementation); return true; } /** * @dev Allows the current owner to relinquish ownership. */ function renounceOwnership() public onlyOwner { emit OwnershipRenounced(getOwner()); _setOwner(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 { require(_newOwner != address(0)); emit OwnershipTransferred(getOwner(), _newOwner); _setOwner(_newOwner); } function getOwner() public view returns(address) { return addressStorage[keccak256(abi.encodePacked("owner"))]; } function _setOwner(address _owner) private { addressStorage[keccak256(abi.encodePacked("owner"))] = _owner; } function getVersion() public view returns(uint256) { return version; } function _setVersion(uint256 _newVersion) private { version = _newVersion; } function getImplementation() public view returns(address) { return implementation; } function _setImplementation(address _newImplementation) private { implementation = _newImplementation; } function getProxyStorage() public view returns(address) { return addressStorage[keccak256(abi.encodePacked("proxyStorage"))]; } function _setProxyStorage(address _proxyStorage) private { addressStorage[keccak256(abi.encodePacked("proxyStorage"))] = _proxyStorage; } } // File: openzeppelin-solidity/contracts/math/SafeMath.sol pragma solidity ^0.4.24; /** * @title SafeMath * @dev Math operations with safety checks that revert on error */ library SafeMath { int256 constant private INT256_MIN = -2**255; /** * @dev Multiplies two unsigned integers, reverts on overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b); return c; } /** * @dev Multiplies two signed integers, reverts on overflow. */ function mul(int256 a, int256 b) internal pure returns (int256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 if (a == 0) { return 0; } require(!(a == -1 && b == INT256_MIN)); // This is the only case of overflow not detected by the check below int256 c = a * b; require(c / a == b); return c; } /** * @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Integer division of two signed integers truncating the quotient, reverts on division by zero. */ function div(int256 a, int256 b) internal pure returns (int256) { require(b != 0); // Solidity only automatically asserts when dividing by 0 require(!(b == -1 && a == INT256_MIN)); // This is the only case of overflow int256 c = a / b; return c; } /** * @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend). */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a); uint256 c = a - b; return c; } /** * @dev Subtracts two signed integers, reverts on overflow. */ function sub(int256 a, int256 b) internal pure returns (int256) { int256 c = a - b; require((b >= 0 && c <= a) || (b < 0 && c > a)); return c; } /** * @dev Adds two unsigned integers, reverts on overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a); return c; } /** * @dev Adds two signed integers, reverts on overflow. */ function add(int256 a, int256 b) internal pure returns (int256) { int256 c = a + b; require((b >= 0 && c >= a) || (b < 0 && c < a)); return c; } /** * @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo), * reverts when dividing by zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b != 0); return a % b; } } // File: contracts/ProxyStorage.sol pragma solidity ^0.4.24; /** * @title Contract used for access and upgradeability to all network contracts * @author LiorRabin */ contract ProxyStorage is EternalStorage { using SafeMath for uint256; /** * @dev Available contract types on the network */ enum ContractTypes { Invalid, Consensus, BlockReward, ProxyStorage, Voting } /** * @dev This event will be emitted when all contract addresses have been initialized by the contract owner */ event ProxyInitialized( address consensus, address blockReward, address voting ); /** * @dev This event will be emitted each time a contract address is updated * @param contractType contract type (See ContractTypes enum) * @param contractAddress contract address set for the contract type */ event AddressSet(uint256 contractType, address contractAddress); /** * @dev This modifier verifies that msg.sender is the owner of the contract */ modifier onlyOwner() { require(msg.sender == addressStorage[OWNER]); _; } /** * @dev This modifier verifies that msg.sender is the voting contract which implement proxy address change */ modifier onlyVoting() { require(msg.sender == getVoting()); _; } /** * @dev Function to be called on contract initialization * @param _consensus address of the network consensus contract */ function initialize(address _consensus) external onlyOwner { require(!isInitialized()); require(_consensus != address(0)); require(_consensus != address(this)); _setConsensus(_consensus); setInitialized(true); } /** * @dev Function to be called to initialize all available contract types addresses */ function initializeAddresses(address _blockReward, address _voting) external onlyOwner { require(!boolStorage[PROXY_STORAGE_ADDRESSES_INITIALIZED]); addressStorage[BLOCK_REWARD] = _blockReward; addressStorage[VOTING] = _voting; boolStorage[PROXY_STORAGE_ADDRESSES_INITIALIZED] = true; emit ProxyInitialized( getConsensus(), _blockReward, _voting ); } /** * @dev Function to be called to set specific contract type address * @param _contractType contract type (See ContractTypes enum) * @param _contractAddress contract address set for the contract type */ function setContractAddress(uint256 _contractType, address _contractAddress) external onlyVoting returns(bool) { if (!isInitialized()) return false; if (_contractAddress == address(0)) return false; bool success = false; if (_contractType == uint256(ContractTypes.Consensus)) { success = EternalStorageProxy(getConsensus()).upgradeTo(_contractAddress); } else if (_contractType == uint256(ContractTypes.BlockReward)) { success = EternalStorageProxy(getBlockReward()).upgradeTo(_contractAddress); } else if (_contractType == uint256(ContractTypes.ProxyStorage)) { success = EternalStorageProxy(this).upgradeTo(_contractAddress); } else if (_contractType == uint256(ContractTypes.Voting)) { success = EternalStorageProxy(getVoting()).upgradeTo(_contractAddress); } if (success) { emit AddressSet(_contractType, _contractAddress); } return success; } /** * @dev Function checking if a contract type is valid one for proxy usage * @param _contractType contract type to check if valid */ function isValidContractType(uint256 _contractType) external pure returns(bool) { return _contractType == uint256(ContractTypes.Consensus) || _contractType == uint256(ContractTypes.BlockReward) || _contractType == uint256(ContractTypes.ProxyStorage) || _contractType == uint256(ContractTypes.Voting); } bytes32 internal constant OWNER = keccak256(abi.encodePacked("owner")); bytes32 internal constant CONSENSUS = keccak256(abi.encodePacked("consensus")); bytes32 internal constant BLOCK_REWARD = keccak256(abi.encodePacked("blockReward")); bytes32 internal constant VOTING = keccak256(abi.encodePacked("voting")); bytes32 internal constant PROXY_STORAGE_ADDRESSES_INITIALIZED = keccak256(abi.encodePacked("proxyStorageAddressesInitialized")); function _setConsensus(address _consensus) private { addressStorage[CONSENSUS] = _consensus; } function getConsensus() public view returns(address){ return addressStorage[CONSENSUS]; } function getBlockReward() public view returns(address){ return addressStorage[BLOCK_REWARD]; } function getVoting() public view returns(address){ return addressStorage[VOTING]; } }
Contract ABI
[{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":""}],"name":"getConsensus","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":""}],"name":"getVoting","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"initializeAddresses","inputs":[{"type":"address","name":"_blockReward"},{"type":"address","name":"_voting"}],"constant":false},{"type":"function","stateMutability":"pure","payable":false,"outputs":[{"type":"bool","name":""}],"name":"isValidContractType","inputs":[{"type":"uint256","name":"_contractType"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bool","name":""}],"name":"isInitialized","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"bool","name":""}],"name":"setContractAddress","inputs":[{"type":"uint256","name":"_contractType"},{"type":"address","name":"_contractAddress"}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"initialize","inputs":[{"type":"address","name":"_consensus"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":""}],"name":"getBlockReward","inputs":[],"constant":true},{"type":"event","name":"ProxyInitialized","inputs":[{"type":"address","name":"consensus","indexed":false},{"type":"address","name":"blockReward","indexed":false},{"type":"address","name":"voting","indexed":false}],"anonymous":false},{"type":"event","name":"AddressSet","inputs":[{"type":"uint256","name":"contractType","indexed":false},{"type":"address","name":"contractAddress","indexed":false}],"anonymous":false}]
Contract Creation Code
0x608060405234801561001057600080fd5b50610d87806100206000396000f3006080604052600436106100745763ffffffff60e060020a600035041663179e740b81146100795780631986d376146100aa57806330b7bdad146100bf57806333875fdd146100e8578063392e53cd14610114578063bb0165b114610129578063c4d66de81461014d578063f89d40861461016e575b600080fd5b34801561008557600080fd5b5061008e610183565b60408051600160a060020a039092168252519081900360200190f35b3480156100b657600080fd5b5061008e610241565b3480156100cb57600080fd5b506100e6600160a060020a03600435811690602435166102b5565b005b3480156100f457600080fd5b506101006004356106f3565b604080519115158252519081900360200190f35b34801561012057600080fd5b50610100610720565b34801561013557600080fd5b50610100600435600160a060020a03602435166107d8565b34801561015957600080fd5b506100e6600160a060020a0360043516610a32565b34801561017a57600080fd5b5061008e610b49565b60006004600060405160200180807f636f6e73656e737573000000000000000000000000000000000000000000000081525060090190506040516020818303038152906040526040518082805190602001908083835b602083106101f85780518252601f1990920191602091820191016101d9565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002054600160a060020a0316949350505050565b60006004600060405160200180807f766f74696e6700000000000000000000000000000000000000000000000000008152506006019050604051602081830303815290604052604051808280519060200190808383602083106101f85780518252601f1990920191602091820191016101d9565b6004600060405160200180807f6f776e657200000000000000000000000000000000000000000000000000000081525060050190506040516020818303038152906040526040518082805190602001908083835b602083106103285780518252601f199092019160209182019101610309565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002054600160a060020a03163314925061037991505057600080fd5b6006600060405160200180807f70726f787953746f72616765416464726573736573496e697469616c697a656481525060200190506040516020818303038152906040526040518082805190602001908083835b602083106103ec5780518252601f1990920191602091820191016103cd565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000205460ff1615925061043691505057600080fd5b816004600060405160200180807f626c6f636b526577617264000000000000000000000000000000000000000000815250600b0190506040516020818303038152906040526040518082805190602001908083835b602083106104aa5780518252601f19909201916020918201910161048b565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285810196909652509283016000908120805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a039790971696909617909555505080517f766f74696e67000000000000000000000000000000000000000000000000000081840152815160068183030181526026909101918290528051859460049490939182918401908083835b6020831061057e5780518252601f19909201916020918201910161055f565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285810196909652509283016000908120805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a039790971696909617909555505080517f70726f787953746f72616765416464726573736573496e697469616c697a65648184015281518082038401815290820191829052805160019460069490939182918401908083835b602083106106505780518252601f199092019160209182019101610631565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020805460ff191694151594909417909355507fffcbdc3faa9d3a4dbee5296e7b8671c3962abe5cc9defb4144df40382ad4713c91506106c59050610183565b60408051600160a060020a039283168152828616602082015291841682820152519081900360600190a15050565b600060018214806107045750600282145b8061070f5750600382145b8061071a5750600482145b92915050565b60006006600060405160200180807f6973496e697469616c697a656400000000000000000000000000000000000000815250600d0190506040516020818303038152906040526040518082805190602001908083835b602083106107955780518252601f199092019160209182019101610776565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000205460ff16949350505050565b6000806107e3610241565b600160a060020a031633146107f757600080fd5b6107ff610720565b151561080e5760009150610a2b565b600160a060020a03831615156108275760009150610a2b565b50600060018414156108c85761083b610183565b600160a060020a0316633659cfe6846040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600087803b15801561089557600080fd5b505af11580156108a9573d6000803e3d6000fd5b505050506040513d60208110156108bf57600080fd5b505190506109dd565b60028414156108d95761083b610b49565b600384141561094357604080517f3659cfe6000000000000000000000000000000000000000000000000000000008152600160a060020a038516600482015290513091633659cfe69160248083019260209291908290030181600087803b15801561089557600080fd5b60048414156109dd57610954610241565b600160a060020a0316633659cfe6846040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600087803b1580156109ae57600080fd5b505af11580156109c2573d6000803e3d6000fd5b505050506040513d60208110156109d857600080fd5b505190505b8015610a275760408051858152600160a060020a038516602082015281517fcb8f0f32182a0f756b1e065dab832c24d2c48fa533912c33552252a7f25bf4ae929181900390910190a15b8091505b5092915050565b6004600060405160200180807f6f776e657200000000000000000000000000000000000000000000000000000081525060050190506040516020818303038152906040526040518082805190602001908083835b60208310610aa55780518252601f199092019160209182019101610a86565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002054600160a060020a031633149250610af691505057600080fd5b610afe610720565b15610b0857600080fd5b600160a060020a0381161515610b1d57600080fd5b600160a060020a038116301415610b3357600080fd5b610b3c81610bbd565b610b466001610c9a565b50565b60006004600060405160200180807f626c6f636b526577617264000000000000000000000000000000000000000000815250600b019050604051602081830303815290604052604051808280519060200190808383602083106101f85780518252601f1990920191602091820191016101d9565b806004600060405160200180807f636f6e73656e737573000000000000000000000000000000000000000000000081525060090190506040516020818303038152906040526040518082805190602001908083835b60208310610c315780518252601f199092019160209182019101610c12565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03959095169490941790935550505050565b806006600060405160200180807f6973496e697469616c697a656400000000000000000000000000000000000000815250600d0190506040516020818303038152906040526040518082805190602001908083835b60208310610d0e5780518252601f199092019160209182019101610cef565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020805460ff191694151594909417909355505050505600a165627a7a72305820c2c2c12433da6ee0a930d11c09d871bead2991a3b6973295c9bd855ed02302b40029
Deployed ByteCode
0x6080604052600436106100745763ffffffff60e060020a600035041663179e740b81146100795780631986d376146100aa57806330b7bdad146100bf57806333875fdd146100e8578063392e53cd14610114578063bb0165b114610129578063c4d66de81461014d578063f89d40861461016e575b600080fd5b34801561008557600080fd5b5061008e610183565b60408051600160a060020a039092168252519081900360200190f35b3480156100b657600080fd5b5061008e610241565b3480156100cb57600080fd5b506100e6600160a060020a03600435811690602435166102b5565b005b3480156100f457600080fd5b506101006004356106f3565b604080519115158252519081900360200190f35b34801561012057600080fd5b50610100610720565b34801561013557600080fd5b50610100600435600160a060020a03602435166107d8565b34801561015957600080fd5b506100e6600160a060020a0360043516610a32565b34801561017a57600080fd5b5061008e610b49565b60006004600060405160200180807f636f6e73656e737573000000000000000000000000000000000000000000000081525060090190506040516020818303038152906040526040518082805190602001908083835b602083106101f85780518252601f1990920191602091820191016101d9565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002054600160a060020a0316949350505050565b60006004600060405160200180807f766f74696e6700000000000000000000000000000000000000000000000000008152506006019050604051602081830303815290604052604051808280519060200190808383602083106101f85780518252601f1990920191602091820191016101d9565b6004600060405160200180807f6f776e657200000000000000000000000000000000000000000000000000000081525060050190506040516020818303038152906040526040518082805190602001908083835b602083106103285780518252601f199092019160209182019101610309565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002054600160a060020a03163314925061037991505057600080fd5b6006600060405160200180807f70726f787953746f72616765416464726573736573496e697469616c697a656481525060200190506040516020818303038152906040526040518082805190602001908083835b602083106103ec5780518252601f1990920191602091820191016103cd565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000205460ff1615925061043691505057600080fd5b816004600060405160200180807f626c6f636b526577617264000000000000000000000000000000000000000000815250600b0190506040516020818303038152906040526040518082805190602001908083835b602083106104aa5780518252601f19909201916020918201910161048b565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285810196909652509283016000908120805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a039790971696909617909555505080517f766f74696e67000000000000000000000000000000000000000000000000000081840152815160068183030181526026909101918290528051859460049490939182918401908083835b6020831061057e5780518252601f19909201916020918201910161055f565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285810196909652509283016000908120805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a039790971696909617909555505080517f70726f787953746f72616765416464726573736573496e697469616c697a65648184015281518082038401815290820191829052805160019460069490939182918401908083835b602083106106505780518252601f199092019160209182019101610631565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020805460ff191694151594909417909355507fffcbdc3faa9d3a4dbee5296e7b8671c3962abe5cc9defb4144df40382ad4713c91506106c59050610183565b60408051600160a060020a039283168152828616602082015291841682820152519081900360600190a15050565b600060018214806107045750600282145b8061070f5750600382145b8061071a5750600482145b92915050565b60006006600060405160200180807f6973496e697469616c697a656400000000000000000000000000000000000000815250600d0190506040516020818303038152906040526040518082805190602001908083835b602083106107955780518252601f199092019160209182019101610776565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000205460ff16949350505050565b6000806107e3610241565b600160a060020a031633146107f757600080fd5b6107ff610720565b151561080e5760009150610a2b565b600160a060020a03831615156108275760009150610a2b565b50600060018414156108c85761083b610183565b600160a060020a0316633659cfe6846040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600087803b15801561089557600080fd5b505af11580156108a9573d6000803e3d6000fd5b505050506040513d60208110156108bf57600080fd5b505190506109dd565b60028414156108d95761083b610b49565b600384141561094357604080517f3659cfe6000000000000000000000000000000000000000000000000000000008152600160a060020a038516600482015290513091633659cfe69160248083019260209291908290030181600087803b15801561089557600080fd5b60048414156109dd57610954610241565b600160a060020a0316633659cfe6846040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600087803b1580156109ae57600080fd5b505af11580156109c2573d6000803e3d6000fd5b505050506040513d60208110156109d857600080fd5b505190505b8015610a275760408051858152600160a060020a038516602082015281517fcb8f0f32182a0f756b1e065dab832c24d2c48fa533912c33552252a7f25bf4ae929181900390910190a15b8091505b5092915050565b6004600060405160200180807f6f776e657200000000000000000000000000000000000000000000000000000081525060050190506040516020818303038152906040526040518082805190602001908083835b60208310610aa55780518252601f199092019160209182019101610a86565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912086528501959095529290920160002054600160a060020a031633149250610af691505057600080fd5b610afe610720565b15610b0857600080fd5b600160a060020a0381161515610b1d57600080fd5b600160a060020a038116301415610b3357600080fd5b610b3c81610bbd565b610b466001610c9a565b50565b60006004600060405160200180807f626c6f636b526577617264000000000000000000000000000000000000000000815250600b019050604051602081830303815290604052604051808280519060200190808383602083106101f85780518252601f1990920191602091820191016101d9565b806004600060405160200180807f636f6e73656e737573000000000000000000000000000000000000000000000081525060090190506040516020818303038152906040526040518082805190602001908083835b60208310610c315780518252601f199092019160209182019101610c12565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03959095169490941790935550505050565b806006600060405160200180807f6973496e697469616c697a656400000000000000000000000000000000000000815250600d0190506040516020818303038152906040526040518082805190602001908083835b60208310610d0e5780518252601f199092019160209182019101610cef565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020805460ff191694151594909417909355505050505600a165627a7a72305820c2c2c12433da6ee0a930d11c09d871bead2991a3b6973295c9bd855ed02302b40029