Source Code
Overview
ETH Balance
0 ETH
More Info
ContractCreator
Multichain Info
N/A
Latest 25 from a total of 280 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Set Smoothing Po... | 3297619 | 7 days ago | IN | 0 ETH | 0.00000008 | ||||
Register Node | 3287933 | 9 days ago | IN | 0 ETH | 0.0009321 | ||||
Set Smoothing Po... | 3282945 | 9 days ago | IN | 0 ETH | 0.0001096 | ||||
Set Smoothing Po... | 3276746 | 10 days ago | IN | 0 ETH | 0.000261 | ||||
Register Node | 3276456 | 10 days ago | IN | 0 ETH | 0.00093205 | ||||
Set Smoothing Po... | 3272795 | 11 days ago | IN | 0 ETH | 0.000261 | ||||
Register Node | 3272598 | 11 days ago | IN | 0 ETH | 0.00093213 | ||||
Set Smoothing Po... | 3270539 | 11 days ago | IN | 0 ETH | 0.0001305 | ||||
Register Node | 3270479 | 11 days ago | IN | 0 ETH | 0.00046602 | ||||
Register Node | 3267461 | 12 days ago | IN | 0 ETH | 0.00093191 | ||||
Set Smoothing Po... | 3267112 | 12 days ago | IN | 0 ETH | 0.000261 | ||||
Register Node | 3265412 | 12 days ago | IN | 0 ETH | 0.00093198 | ||||
Set Smoothing Po... | 3264650 | 12 days ago | IN | 0 ETH | 0.000261 | ||||
Register Node | 3264388 | 12 days ago | IN | 0 ETH | 0.00093205 | ||||
Set Smoothing Po... | 3260171 | 13 days ago | IN | 0 ETH | 0.000261 | ||||
Register Node | 3260163 | 13 days ago | IN | 0 ETH | 0.00093213 | ||||
Register Node | 3253405 | 14 days ago | IN | 0 ETH | 0.00016334 | ||||
Register Node | 3253401 | 14 days ago | IN | 0 ETH | 0.00016334 | ||||
Register Node | 3253401 | 14 days ago | IN | 0 ETH | 0.00093191 | ||||
Register Node | 3239303 | 16 days ago | IN | 0 ETH | 0.00093191 | ||||
Register Node | 3230904 | 17 days ago | IN | 0 ETH | 0.00093191 | ||||
Register Node | 3227020 | 18 days ago | IN | 0 ETH | 0.00093191 | ||||
Register Node | 3225805 | 18 days ago | IN | 0 ETH | 0.00093191 | ||||
Set Smoothing Po... | 3213211 | 20 days ago | IN | 0 ETH | 0.000261 | ||||
Register Node | 3211008 | 20 days ago | IN | 0 ETH | 0.00093191 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
RocketNodeManager
Compiler Version
v0.8.18+commit.87f61d96
Contract Source Code (Solidity Standard Json-Input format)
/** * . * / \ * |.'.| * |'.'| * ,'| |`. * |,-'-|-'-.| * __|_| | _ _ _____ _ * | ___ \| | | | | | ___ \ | | * | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | | * | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| | * | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | | * \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_| * +---------------------------------------------------+ * | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM 2.0 | * +---------------------------------------------------+ * * Rocket Pool is a first-of-its-kind ETH2 Proof of Stake protocol, designed to be community owned, * decentralised, trustless and compatible with staking in Ethereum 2.0. * * For more information about Rocket Pool, visit https://rocketpool.net * * Authors: David Rugendyke, Jake Pospischil, Kane Wallmann, Darren Langley, Joe Clapis, Nick Doherty * */ // SPDX-License-Identifier: GPL-3.0-only pragma solidity 0.8.18; pragma abicoder v2; import "../RocketBase.sol"; import "../../types/MinipoolStatus.sol"; import "../../types/NodeDetails.sol"; import "../../interface/node/RocketNodeManagerInterface.sol"; import "../../interface/dao/protocol/settings/RocketDAOProtocolSettingsNodeInterface.sol"; import "../../interface/util/AddressSetStorageInterface.sol"; import "../../interface/node/RocketNodeDistributorFactoryInterface.sol"; import "../../interface/minipool/RocketMinipoolManagerInterface.sol"; import "../../interface/node/RocketNodeDistributorInterface.sol"; import "../../interface/dao/node/settings/RocketDAONodeTrustedSettingsRewardsInterface.sol"; import "../../interface/dao/protocol/settings/RocketDAOProtocolSettingsRewardsInterface.sol"; import "../../interface/node/RocketNodeStakingInterface.sol"; import "../../interface/node/RocketNodeDepositInterface.sol"; import "../../interface/dao/protocol/settings/RocketDAOProtocolSettingsMinipoolInterface.sol"; import "../../interface/util/IERC20.sol"; import "../../interface/network/RocketNetworkSnapshotsInterface.sol"; /// @notice Node registration and management contract RocketNodeManager is RocketBase, RocketNodeManagerInterface { // Events event NodeRegistered(address indexed node, uint256 time); event NodeTimezoneLocationSet(address indexed node, uint256 time); event NodeRewardNetworkChanged(address indexed node, uint256 network); event NodeSmoothingPoolStateChanged(address indexed node, bool state); event NodeRPLWithdrawalAddressSet(address indexed node, address indexed withdrawalAddress, uint256 time); event NodeRPLWithdrawalAddressUnset(address indexed node, uint256 time); constructor(RocketStorageInterface _rocketStorageAddress) RocketBase(_rocketStorageAddress) { version = 4; } /// @notice Get the number of nodes in the network function getNodeCount() override public view returns (uint256) { AddressSetStorageInterface addressSetStorage = AddressSetStorageInterface(getContractAddress("addressSetStorage")); return addressSetStorage.getCount(keccak256(abi.encodePacked("nodes.index"))); } /// @notice Get a breakdown of the number of nodes per timezone function getNodeCountPerTimezone(uint256 _offset, uint256 _limit) override external view returns (TimezoneCount[] memory) { // Get contracts AddressSetStorageInterface addressSetStorage = AddressSetStorageInterface(getContractAddress("addressSetStorage")); // Precompute node key bytes32 nodeKey = keccak256(abi.encodePacked("nodes.index")); // Calculate range uint256 totalNodes = addressSetStorage.getCount(nodeKey); uint256 max = _offset + _limit; if (max > totalNodes || _limit == 0) { max = totalNodes; } // Create an array with as many elements as there are potential values to return TimezoneCount[] memory counts = new TimezoneCount[](max - _offset); uint256 uniqueTimezoneCount = 0; // Iterate the minipool range for (uint256 i = _offset; i < max; ++i) { address nodeAddress = addressSetStorage.getItem(nodeKey, i); string memory timezone = getString(keccak256(abi.encodePacked("node.timezone.location", nodeAddress))); // Find existing entry in our array bool existing = false; for (uint256 j = 0; j < uniqueTimezoneCount; ++j) { if (keccak256(bytes(counts[j].timezone)) == keccak256(bytes(timezone))) { existing = true; // Increment the counter counts[j].count++; break; } } // Entry was not found, so create a new one if (!existing) { counts[uniqueTimezoneCount].timezone = timezone; counts[uniqueTimezoneCount].count = 1; uniqueTimezoneCount++; } } // Dirty hack to cut unused elements off end of return value assembly { mstore(counts, uniqueTimezoneCount) } return counts; } /// @notice Get a node address by index function getNodeAt(uint256 _index) override external view returns (address) { AddressSetStorageInterface addressSetStorage = AddressSetStorageInterface(getContractAddress("addressSetStorage")); return addressSetStorage.getItem(keccak256(abi.encodePacked("nodes.index")), _index); } /// @notice Check whether a node exists function getNodeExists(address _nodeAddress) override public view returns (bool) { return getBool(keccak256(abi.encodePacked("node.exists", _nodeAddress))); } /// @notice Get a node's current withdrawal address function getNodeWithdrawalAddress(address _nodeAddress) override public view returns (address) { return rocketStorage.getNodeWithdrawalAddress(_nodeAddress); } /// @notice Get a node's pending withdrawal address function getNodePendingWithdrawalAddress(address _nodeAddress) override public view returns (address) { return rocketStorage.getNodePendingWithdrawalAddress(_nodeAddress); } /// @notice Get a node's current RPL withdrawal address function getNodeRPLWithdrawalAddress(address _nodeAddress) override public view returns (address) { address withdrawalAddress = getAddress(keccak256(abi.encodePacked("node.rpl.withdrawal.address", _nodeAddress))); if (withdrawalAddress == address(0)) { // Defaults to current withdrawal address if unset return rocketStorage.getNodeWithdrawalAddress(_nodeAddress); } return withdrawalAddress; } /// @notice Get a node's pending RPL withdrawal address function getNodePendingRPLWithdrawalAddress(address _nodeAddress) override public view returns (address) { return getAddress(keccak256(abi.encodePacked("node.pending.rpl.withdrawal.address", _nodeAddress))); } /// @notice Returns true if a node has set an RPL withdrawal address function getNodeRPLWithdrawalAddressIsSet(address _nodeAddress) override external view returns (bool) { return(getAddress(keccak256(abi.encodePacked("node.rpl.withdrawal.address", _nodeAddress))) != address(0)); } /// @notice Unsets a node operator's RPL withdrawal address returning it to the default function unsetRPLWithdrawalAddress(address _nodeAddress) external override onlyRegisteredNode(_nodeAddress) { bytes32 addressKey = keccak256(abi.encodePacked("node.rpl.withdrawal.address", _nodeAddress)); // Confirm the transaction is from the node's current RPL withdrawal address require(getAddress(addressKey) == msg.sender, "Only a tx from a node's RPL withdrawal address can unset it"); // Unset the address deleteAddress(addressKey); // Emit withdrawal address unset event emit NodeRPLWithdrawalAddressUnset(_nodeAddress, block.timestamp); } // @notice Set a node's RPL withdrawal address function setRPLWithdrawalAddress(address _nodeAddress, address _newRPLWithdrawalAddress, bool _confirm) external override onlyRegisteredNode(_nodeAddress) { // Check new RPL withdrawal address require(_newRPLWithdrawalAddress != address(0x0), "Invalid RPL withdrawal address"); // Confirm the transaction is from the node's current RPL withdrawal address address withdrawalAddress = getNodeRPLWithdrawalAddress(_nodeAddress); require(withdrawalAddress == msg.sender, "Only a tx from a node's RPL withdrawal address can update it"); // Update immediately if confirmed if (_confirm) { // Delete any existing pending update deleteAddress(keccak256(abi.encodePacked("node.pending.rpl.withdrawal.address", _nodeAddress))); // Perform the update updateRPLWithdrawalAddress(_nodeAddress, _newRPLWithdrawalAddress); } // Set pending withdrawal address if not confirmed else { setAddress(keccak256(abi.encodePacked("node.pending.rpl.withdrawal.address", _nodeAddress)), _newRPLWithdrawalAddress); } } /// @notice Confirm a node's new RPL withdrawal address function confirmRPLWithdrawalAddress(address _nodeAddress) external override onlyRegisteredNode(_nodeAddress) { bytes32 pendingKey = keccak256(abi.encodePacked("node.pending.rpl.withdrawal.address", _nodeAddress)); // Get node by pending withdrawal address require(getAddress(pendingKey) == msg.sender, "Confirmation must come from the pending RPL withdrawal address"); deleteAddress(pendingKey); // Update withdrawal address updateRPLWithdrawalAddress(_nodeAddress, msg.sender); } /// @notice Update a node's withdrawal address function updateRPLWithdrawalAddress(address _nodeAddress, address _newWithdrawalAddress) private { // Set new withdrawal address setAddress(keccak256(abi.encodePacked("node.rpl.withdrawal.address", _nodeAddress)), _newWithdrawalAddress); // Emit withdrawal address set event emit NodeRPLWithdrawalAddressSet(_nodeAddress, _newWithdrawalAddress, block.timestamp); } /// @notice Get a node's timezone location function getNodeTimezoneLocation(address _nodeAddress) override public view returns (string memory) { return getString(keccak256(abi.encodePacked("node.timezone.location", _nodeAddress))); } /// @notice Register a new node with Rocket Pool function registerNode(string calldata _timezoneLocation) override external onlyLatestContract("rocketNodeManager", address(this)) { // Load contracts RocketDAOProtocolSettingsNodeInterface rocketDAOProtocolSettingsNode = RocketDAOProtocolSettingsNodeInterface(getContractAddress("rocketDAOProtocolSettingsNode")); AddressSetStorageInterface addressSetStorage = AddressSetStorageInterface(getContractAddress("addressSetStorage")); RocketNetworkSnapshotsInterface rocketNetworkSnapshots = RocketNetworkSnapshotsInterface(getContractAddress("rocketNetworkSnapshots")); // Check node settings require(rocketDAOProtocolSettingsNode.getRegistrationEnabled(), "Rocket Pool node registrations are currently disabled"); // Check timezone location require(bytes(_timezoneLocation).length >= 4, "The timezone location is invalid"); // Initialise node data setBool(keccak256(abi.encodePacked("node.exists", msg.sender)), true); setBool(keccak256(abi.encodePacked("node.voting.enabled", msg.sender)), true); setString(keccak256(abi.encodePacked("node.timezone.location", msg.sender)), _timezoneLocation); // Add node to index bytes32 nodeIndexKey = keccak256(abi.encodePacked("nodes.index")); addressSetStorage.addItem(nodeIndexKey, msg.sender); // Initialise fee distributor for this node _initialiseFeeDistributor(msg.sender); // Set node registration time (uses old storage key name for backwards compatibility) setUint(keccak256(abi.encodePacked("rewards.pool.claim.contract.registered.time", "rocketClaimNode", msg.sender)), block.timestamp); // Update count rocketNetworkSnapshots.push(keccak256(abi.encodePacked("node.count")), uint224(addressSetStorage.getCount(nodeIndexKey))); // Default voting delegate to themself rocketNetworkSnapshots.push(keccak256(abi.encodePacked("node.delegate", msg.sender)), uint224(uint160(msg.sender))); // Emit node registered event emit NodeRegistered(msg.sender, block.timestamp); } /// @notice Gets the timestamp of when a node was registered function getNodeRegistrationTime(address _nodeAddress) onlyRegisteredNode(_nodeAddress) override public view returns (uint256) { return getUint(keccak256(abi.encodePacked("rewards.pool.claim.contract.registered.time", "rocketClaimNode", _nodeAddress))); } /// @notice Set a node's timezone location function setTimezoneLocation(string calldata _timezoneLocation) override external onlyLatestContract("rocketNodeManager", address(this)) onlyRegisteredNode(msg.sender) { // Check timezone location require(bytes(_timezoneLocation).length >= 4, "The timezone location is invalid"); // Set timezone location setString(keccak256(abi.encodePacked("node.timezone.location", msg.sender)), _timezoneLocation); // Emit node timezone location set event emit NodeTimezoneLocationSet(msg.sender, block.timestamp); } /// @notice Returns true if node has initialised their fee distributor contract function getFeeDistributorInitialised(address _nodeAddress) override public view returns (bool) { // Load contracts RocketNodeDistributorFactoryInterface rocketNodeDistributorFactory = RocketNodeDistributorFactoryInterface(getContractAddress("rocketNodeDistributorFactory")); // Get distributor address address contractAddress = rocketNodeDistributorFactory.getProxyAddress(_nodeAddress); // Check if contract exists at that address uint32 codeSize; assembly { codeSize := extcodesize(contractAddress) } return codeSize > 0; } /// @notice Node operators created before the distributor was implemented must call this to setup their distributor contract function initialiseFeeDistributor() override external onlyLatestContract("rocketNodeManager", address(this)) onlyRegisteredNode(msg.sender) { // Prevent multiple calls require(!getFeeDistributorInitialised(msg.sender), "Already initialised"); // Load contracts RocketMinipoolManagerInterface rocketMinipoolManager = RocketMinipoolManagerInterface(getContractAddress("rocketMinipoolManager")); // Calculate and set current average fee numerator uint256 count = rocketMinipoolManager.getNodeMinipoolCount(msg.sender); if (count > 0){ uint256 numerator = 0; // Note: this loop is safe as long as all current node operators at the time of upgrade have few enough minipools for (uint256 i = 0; i < count; ++i) { RocketMinipoolInterface minipool = RocketMinipoolInterface(rocketMinipoolManager.getNodeMinipoolAt(msg.sender, i)); if (minipool.getStatus() == MinipoolStatus.Staking){ numerator = numerator + minipool.getNodeFee(); } } setUint(keccak256(abi.encodePacked("node.average.fee.numerator", msg.sender)), numerator); } // Create the distributor contract _initialiseFeeDistributor(msg.sender); } /// @notice Deploys the fee distributor contract for a given node function _initialiseFeeDistributor(address _nodeAddress) internal { // Load contracts RocketNodeDistributorFactoryInterface rocketNodeDistributorFactory = RocketNodeDistributorFactoryInterface(getContractAddress("rocketNodeDistributorFactory")); // Create the distributor proxy rocketNodeDistributorFactory.createProxy(_nodeAddress); } /// @notice Calculates a nodes average node fee function getAverageNodeFee(address _nodeAddress) override external view returns (uint256) { // Load contracts RocketMinipoolManagerInterface rocketMinipoolManager = RocketMinipoolManagerInterface(getContractAddress("rocketMinipoolManager")); RocketNodeDepositInterface rocketNodeDeposit = RocketNodeDepositInterface(getContractAddress("rocketNodeDeposit")); RocketDAOProtocolSettingsMinipoolInterface rocketDAOProtocolSettingsMinipool = RocketDAOProtocolSettingsMinipoolInterface(getContractAddress("rocketDAOProtocolSettingsMinipool")); // Get valid deposit amounts uint256[] memory depositSizes = rocketNodeDeposit.getDepositAmounts(); // Setup memory for calculations uint256[] memory depositWeights = new uint256[](depositSizes.length); uint256[] memory depositCounts = new uint256[](depositSizes.length); uint256 depositWeightTotal; uint256 totalCount; uint256 launchAmount = rocketDAOProtocolSettingsMinipool.getLaunchBalance(); // Retrieve the number of staking minipools per deposit size for (uint256 i = 0; i < depositSizes.length; ++i) { depositCounts[i] = rocketMinipoolManager.getNodeStakingMinipoolCountBySize(_nodeAddress, depositSizes[i]); totalCount = totalCount + depositCounts[i]; } if (totalCount == 0) { return 0; } // Calculate the weights of each deposit size for (uint256 i = 0; i < depositSizes.length; ++i) { depositWeights[i] = (launchAmount - depositSizes[i]) * depositCounts[i]; depositWeightTotal = depositWeightTotal + depositWeights[i]; } for (uint256 i = 0; i < depositSizes.length; ++i) { depositWeights[i] = depositWeights[i] * calcBase / depositWeightTotal; } // Calculate the weighted average uint256 weightedAverage = 0; for (uint256 i = 0; i < depositSizes.length; ++i) { if (depositCounts[i] > 0) { bytes32 numeratorKey; if (depositSizes[i] == 16 ether) { numeratorKey = keccak256(abi.encodePacked("node.average.fee.numerator", _nodeAddress)); } else { numeratorKey = keccak256(abi.encodePacked("node.average.fee.numerator", _nodeAddress, depositSizes[i])); } uint256 numerator = getUint(numeratorKey); weightedAverage = weightedAverage + (numerator * depositWeights[i] / depositCounts[i]); } } return weightedAverage / calcBase; } /// @notice Designates which network a node would like their rewards relayed to function setRewardNetwork(address _nodeAddress, uint256 _network) override external onlyLatestContract("rocketNodeManager", address(this)) { // Confirm the transaction is from the node's current withdrawal address address withdrawalAddress = rocketStorage.getNodeWithdrawalAddress(_nodeAddress); require(withdrawalAddress == msg.sender, "Only a tx from a node's withdrawal address can change reward network"); // Check network is enabled RocketDAONodeTrustedSettingsRewardsInterface rocketDAONodeTrustedSettingsRewards = RocketDAONodeTrustedSettingsRewardsInterface(getContractAddress("rocketDAONodeTrustedSettingsRewards")); require(rocketDAONodeTrustedSettingsRewards.getNetworkEnabled(_network), "Network is not enabled"); // Set the network setUint(keccak256(abi.encodePacked("node.reward.network", _nodeAddress)), _network); // Emit event emit NodeRewardNetworkChanged(_nodeAddress, _network); } /// @notice Returns which network a node has designated as their desired reward network function getRewardNetwork(address _nodeAddress) override public view onlyLatestContract("rocketNodeManager", address(this)) returns (uint256) { return getUint(keccak256(abi.encodePacked("node.reward.network", _nodeAddress))); } /// @notice Allows a node to register or deregister from the smoothing pool function setSmoothingPoolRegistrationState(bool _state) override external onlyLatestContract("rocketNodeManager", address(this)) onlyRegisteredNode(msg.sender) { // Ensure registration is enabled RocketDAOProtocolSettingsNodeInterface daoSettingsNode = RocketDAOProtocolSettingsNodeInterface(getContractAddress("rocketDAOProtocolSettingsNode")); require(daoSettingsNode.getSmoothingPoolRegistrationEnabled(), "Smoothing pool registrations are not active"); // Precompute storage keys bytes32 changeKey = keccak256(abi.encodePacked("node.smoothing.pool.changed.time", msg.sender)); bytes32 stateKey = keccak256(abi.encodePacked("node.smoothing.pool.state", msg.sender)); // Get from the DAO settings RocketDAOProtocolSettingsRewardsInterface daoSettingsRewards = RocketDAOProtocolSettingsRewardsInterface(getContractAddress("rocketDAOProtocolSettingsRewards")); uint256 rewardInterval = daoSettingsRewards.getRewardsClaimIntervalTime(); // Ensure node operator has waited the required time uint256 lastChange = getUint(changeKey); require(block.timestamp >= lastChange + rewardInterval, "Not enough time has passed since changing state"); // Ensure state is actually changing require(getBool(stateKey) != _state, "Invalid state change"); // Update registration state setUint(changeKey, block.timestamp); setBool(stateKey, _state); // Emit state change event emit NodeSmoothingPoolStateChanged(msg.sender, _state); } /// @notice Returns whether a node is registered or not from the smoothing pool function getSmoothingPoolRegistrationState(address _nodeAddress) override public view returns (bool) { return getBool(keccak256(abi.encodePacked("node.smoothing.pool.state", _nodeAddress))); } /// @notice Returns the timestamp of when the node last changed their smoothing pool registration state function getSmoothingPoolRegistrationChanged(address _nodeAddress) override external view returns (uint256) { return getUint(keccak256(abi.encodePacked("node.smoothing.pool.changed.time", _nodeAddress))); } /// @notice Returns the sum of nodes that are registered for the smoothing pool between _offset and (_offset + _limit) function getSmoothingPoolRegisteredNodeCount(uint256 _offset, uint256 _limit) override external view returns (uint256) { // Get contracts AddressSetStorageInterface addressSetStorage = AddressSetStorageInterface(getContractAddress("addressSetStorage")); // Precompute node key bytes32 nodeKey = keccak256(abi.encodePacked("nodes.index")); // Iterate over the requested minipool range uint256 totalNodes = getNodeCount(); uint256 max = _offset + _limit; if (max > totalNodes || _limit == 0) { max = totalNodes; } uint256 count = 0; for (uint256 i = _offset; i < max; ++i) { address nodeAddress = addressSetStorage.getItem(nodeKey, i); if (getSmoothingPoolRegistrationState(nodeAddress)) { count++; } } return count; } /// @notice Convenience function to return all on-chain details about a given node /// @param _nodeAddress Address of the node to query details for function getNodeDetails(address _nodeAddress) override public view returns (NodeDetails memory nodeDetails) { // Get contracts RocketNodeStakingInterface rocketNodeStaking = RocketNodeStakingInterface(getContractAddress("rocketNodeStaking")); RocketNodeDepositInterface rocketNodeDeposit = RocketNodeDepositInterface(getContractAddress("rocketNodeDeposit")); RocketNodeDistributorFactoryInterface rocketNodeDistributorFactory = RocketNodeDistributorFactoryInterface(getContractAddress("rocketNodeDistributorFactory")); RocketMinipoolManagerInterface rocketMinipoolManager = RocketMinipoolManagerInterface(getContractAddress("rocketMinipoolManager")); IERC20 rocketTokenRETH = IERC20(getContractAddress("rocketTokenRETH")); IERC20 rocketTokenRPL = IERC20(getContractAddress("rocketTokenRPL")); IERC20 rocketTokenRPLFixedSupply = IERC20(getContractAddress("rocketTokenRPLFixedSupply")); // Node details nodeDetails.nodeAddress = _nodeAddress; nodeDetails.withdrawalAddress = rocketStorage.getNodeWithdrawalAddress(_nodeAddress); nodeDetails.pendingWithdrawalAddress = rocketStorage.getNodePendingWithdrawalAddress(_nodeAddress); nodeDetails.exists = getNodeExists(_nodeAddress); nodeDetails.registrationTime = getNodeRegistrationTime(_nodeAddress); nodeDetails.timezoneLocation = getNodeTimezoneLocation(_nodeAddress); nodeDetails.feeDistributorInitialised = getFeeDistributorInitialised(_nodeAddress); nodeDetails.rewardNetwork = getRewardNetwork(_nodeAddress); // Staking details nodeDetails.rplStake = rocketNodeStaking.getNodeRPLStake(_nodeAddress); nodeDetails.effectiveRPLStake = rocketNodeStaking.getNodeEffectiveRPLStake(_nodeAddress); nodeDetails.minimumRPLStake = rocketNodeStaking.getNodeMinimumRPLStake(_nodeAddress); nodeDetails.maximumRPLStake = rocketNodeStaking.getNodeMaximumRPLStake(_nodeAddress); nodeDetails.ethMatched = rocketNodeStaking.getNodeETHMatched(_nodeAddress); nodeDetails.ethMatchedLimit = rocketNodeStaking.getNodeETHMatchedLimit(_nodeAddress); // Distributor details nodeDetails.feeDistributorAddress = rocketNodeDistributorFactory.getProxyAddress(_nodeAddress); uint256 distributorBalance = nodeDetails.feeDistributorAddress.balance; RocketNodeDistributorInterface distributor = RocketNodeDistributorInterface(nodeDetails.feeDistributorAddress); nodeDetails.distributorBalanceNodeETH = distributor.getNodeShare(); nodeDetails.distributorBalanceUserETH = distributorBalance - nodeDetails.distributorBalanceNodeETH; // Minipool details nodeDetails.minipoolCount = rocketMinipoolManager.getNodeMinipoolCount(_nodeAddress); // Balance details nodeDetails.balanceETH = _nodeAddress.balance; nodeDetails.balanceRETH = rocketTokenRETH.balanceOf(_nodeAddress); nodeDetails.balanceRPL = rocketTokenRPL.balanceOf(_nodeAddress); nodeDetails.balanceOldRPL = rocketTokenRPLFixedSupply.balanceOf(_nodeAddress); nodeDetails.depositCreditBalance = rocketNodeDeposit.getNodeDepositCredit(_nodeAddress); // Return return nodeDetails; } /// @notice Returns a slice of the node operator address set /// @param _offset The starting point into the slice /// @param _limit The maximum number of results to return function getNodeAddresses(uint256 _offset, uint256 _limit) override external view returns (address[] memory) { // Get contracts AddressSetStorageInterface addressSetStorage = AddressSetStorageInterface(getContractAddress("addressSetStorage")); // Precompute node key bytes32 nodeKey = keccak256(abi.encodePacked("nodes.index")); // Iterate over the requested minipool range uint256 totalNodes = getNodeCount(); uint256 max = _offset + _limit; if (max > totalNodes || _limit == 0) { max = totalNodes; } // Create array big enough for every minipool address[] memory nodes = new address[](max - _offset); uint256 total = 0; for (uint256 i = _offset; i < max; ++i) { nodes[total] = addressSetStorage.getItem(nodeKey, i); total++; } // Dirty hack to cut unused elements off end of return value assembly { mstore(nodes, total) } return nodes; } }
/** * . * / \ * |.'.| * |'.'| * ,'| |`. * |,-'-|-'-.| * __|_| | _ _ _____ _ * | ___ \| | | | | | ___ \ | | * | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | | * | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| | * | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | | * \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_| * +---------------------------------------------------+ * | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM 2.0 | * +---------------------------------------------------+ * * Rocket Pool is a first-of-its-kind ETH2 Proof of Stake protocol, designed to be community owned, * decentralised, trustless and compatible with staking in Ethereum 2.0. * * For more information about Rocket Pool, visit https://rocketpool.net * * Authors: David Rugendyke, Jake Pospischil, Kane Wallmann, Darren Langley, Joe Clapis, Nick Doherty * */ pragma solidity >0.5.0 <0.9.0; // SPDX-License-Identifier: GPL-3.0-only interface RocketStorageInterface { // Deploy status function getDeployedStatus() external view returns (bool); // Guardian function getGuardian() external view returns(address); function setGuardian(address _newAddress) external; function confirmGuardian() external; // Getters function getAddress(bytes32 _key) external view returns (address); function getUint(bytes32 _key) external view returns (uint); function getString(bytes32 _key) external view returns (string memory); function getBytes(bytes32 _key) external view returns (bytes memory); function getBool(bytes32 _key) external view returns (bool); function getInt(bytes32 _key) external view returns (int); function getBytes32(bytes32 _key) external view returns (bytes32); // Setters function setAddress(bytes32 _key, address _value) external; function setUint(bytes32 _key, uint _value) external; function setString(bytes32 _key, string calldata _value) external; function setBytes(bytes32 _key, bytes calldata _value) external; function setBool(bytes32 _key, bool _value) external; function setInt(bytes32 _key, int _value) external; function setBytes32(bytes32 _key, bytes32 _value) external; // Deleters function deleteAddress(bytes32 _key) external; function deleteUint(bytes32 _key) external; function deleteString(bytes32 _key) external; function deleteBytes(bytes32 _key) external; function deleteBool(bytes32 _key) external; function deleteInt(bytes32 _key) external; function deleteBytes32(bytes32 _key) external; // Arithmetic function addUint(bytes32 _key, uint256 _amount) external; function subUint(bytes32 _key, uint256 _amount) external; // Protected storage function getNodeWithdrawalAddress(address _nodeAddress) external view returns (address); function getNodePendingWithdrawalAddress(address _nodeAddress) external view returns (address); function setWithdrawalAddress(address _nodeAddress, address _newWithdrawalAddress, bool _confirm) external; function confirmWithdrawalAddress(address _nodeAddress) external; }
/** * . * / \ * |.'.| * |'.'| * ,'| |`. * |,-'-|-'-.| * __|_| | _ _ _____ _ * | ___ \| | | | | | ___ \ | | * | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | | * | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| | * | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | | * \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_| * +---------------------------------------------------+ * | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM 2.0 | * +---------------------------------------------------+ * * Rocket Pool is a first-of-its-kind ETH2 Proof of Stake protocol, designed to be community owned, * decentralised, trustless and compatible with staking in Ethereum 2.0. * * For more information about Rocket Pool, visit https://rocketpool.net * * Authors: David Rugendyke, Jake Pospischil, Kane Wallmann, Darren Langley, Joe Clapis, Nick Doherty * */ pragma solidity >0.5.0 <0.9.0; // SPDX-License-Identifier: GPL-3.0-only import "../interface/RocketStorageInterface.sol"; /// @title Base settings / modifiers for each contract in Rocket Pool /// @author David Rugendyke abstract contract RocketBase { // Calculate using this as the base uint256 constant calcBase = 1 ether; // Version of the contract uint8 public version; // The main storage contract where primary persistant storage is maintained RocketStorageInterface rocketStorage = RocketStorageInterface(address(0)); /*** Modifiers **********************************************************/ /** * @dev Throws if called by any sender that doesn't match a Rocket Pool network contract */ modifier onlyLatestNetworkContract() { require(getBool(keccak256(abi.encodePacked("contract.exists", msg.sender))), "Invalid or outdated network contract"); _; } /** * @dev Throws if called by any sender that doesn't match one of the supplied contract or is the latest version of that contract */ modifier onlyLatestContract(string memory _contractName, address _contractAddress) { require(_contractAddress == getAddress(keccak256(abi.encodePacked("contract.address", _contractName))), "Invalid or outdated contract"); _; } /** * @dev Throws if called by any sender that isn't a registered node */ modifier onlyRegisteredNode(address _nodeAddress) { require(getBool(keccak256(abi.encodePacked("node.exists", _nodeAddress))), "Invalid node"); _; } /** * @dev Throws if called by any sender that isn't a trusted node DAO member */ modifier onlyTrustedNode(address _nodeAddress) { require(getBool(keccak256(abi.encodePacked("dao.trustednodes.", "member", _nodeAddress))), "Invalid trusted node"); _; } /** * @dev Throws if called by any sender that isn't a registered minipool */ modifier onlyRegisteredMinipool(address _minipoolAddress) { require(getBool(keccak256(abi.encodePacked("minipool.exists", _minipoolAddress))), "Invalid minipool"); _; } /** * @dev Throws if called by any account other than a guardian account (temporary account allowed access to settings before DAO is fully enabled) */ modifier onlyGuardian() { require(msg.sender == rocketStorage.getGuardian(), "Account is not a temporary guardian"); _; } /*** Methods **********************************************************/ /// @dev Set the main Rocket Storage address constructor(RocketStorageInterface _rocketStorageAddress) { // Update the contract address rocketStorage = RocketStorageInterface(_rocketStorageAddress); } /// @dev Get the address of a network contract by name function getContractAddress(string memory _contractName) internal view returns (address) { // Get the current contract address address contractAddress = getAddress(keccak256(abi.encodePacked("contract.address", _contractName))); // Check it require(contractAddress != address(0x0), "Contract not found"); // Return return contractAddress; } /// @dev Get the address of a network contract by name (returns address(0x0) instead of reverting if contract does not exist) function getContractAddressUnsafe(string memory _contractName) internal view returns (address) { // Get the current contract address address contractAddress = getAddress(keccak256(abi.encodePacked("contract.address", _contractName))); // Return return contractAddress; } /// @dev Get the name of a network contract by address function getContractName(address _contractAddress) internal view returns (string memory) { // Get the contract name string memory contractName = getString(keccak256(abi.encodePacked("contract.name", _contractAddress))); // Check it require(bytes(contractName).length > 0, "Contract not found"); // Return return contractName; } /// @dev Get revert error message from a .call method function getRevertMsg(bytes memory _returnData) internal pure returns (string memory) { // If the _res length is less than 68, then the transaction failed silently (without a revert message) if (_returnData.length < 68) return "Transaction reverted silently"; assembly { // Slice the sighash. _returnData := add(_returnData, 0x04) } return abi.decode(_returnData, (string)); // All that remains is the revert string } /*** Rocket Storage Methods ****************************************/ // Note: Unused helpers have been removed to keep contract sizes down /// @dev Storage get methods function getAddress(bytes32 _key) internal view returns (address) { return rocketStorage.getAddress(_key); } function getUint(bytes32 _key) internal view returns (uint) { return rocketStorage.getUint(_key); } function getString(bytes32 _key) internal view returns (string memory) { return rocketStorage.getString(_key); } function getBytes(bytes32 _key) internal view returns (bytes memory) { return rocketStorage.getBytes(_key); } function getBool(bytes32 _key) internal view returns (bool) { return rocketStorage.getBool(_key); } function getInt(bytes32 _key) internal view returns (int) { return rocketStorage.getInt(_key); } function getBytes32(bytes32 _key) internal view returns (bytes32) { return rocketStorage.getBytes32(_key); } /// @dev Storage set methods function setAddress(bytes32 _key, address _value) internal { rocketStorage.setAddress(_key, _value); } function setUint(bytes32 _key, uint _value) internal { rocketStorage.setUint(_key, _value); } function setString(bytes32 _key, string memory _value) internal { rocketStorage.setString(_key, _value); } function setBytes(bytes32 _key, bytes memory _value) internal { rocketStorage.setBytes(_key, _value); } function setBool(bytes32 _key, bool _value) internal { rocketStorage.setBool(_key, _value); } function setInt(bytes32 _key, int _value) internal { rocketStorage.setInt(_key, _value); } function setBytes32(bytes32 _key, bytes32 _value) internal { rocketStorage.setBytes32(_key, _value); } /// @dev Storage delete methods function deleteAddress(bytes32 _key) internal { rocketStorage.deleteAddress(_key); } function deleteUint(bytes32 _key) internal { rocketStorage.deleteUint(_key); } function deleteString(bytes32 _key) internal { rocketStorage.deleteString(_key); } function deleteBytes(bytes32 _key) internal { rocketStorage.deleteBytes(_key); } function deleteBool(bytes32 _key) internal { rocketStorage.deleteBool(_key); } function deleteInt(bytes32 _key) internal { rocketStorage.deleteInt(_key); } function deleteBytes32(bytes32 _key) internal { rocketStorage.deleteBytes32(_key); } /// @dev Storage arithmetic methods function addUint(bytes32 _key, uint256 _amount) internal { rocketStorage.addUint(_key, _amount); } function subUint(bytes32 _key, uint256 _amount) internal { rocketStorage.subUint(_key, _amount); } }
/** * . * / \ * |.'.| * |'.'| * ,'| |`. * |,-'-|-'-.| * __|_| | _ _ _____ _ * | ___ \| | | | | | ___ \ | | * | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | | * | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| | * | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | | * \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_| * +---------------------------------------------------+ * | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM 2.0 | * +---------------------------------------------------+ * * Rocket Pool is a first-of-its-kind ETH2 Proof of Stake protocol, designed to be community owned, * decentralised, trustless and compatible with staking in Ethereum 2.0. * * For more information about Rocket Pool, visit https://rocketpool.net * * Authors: David Rugendyke, Jake Pospischil, Kane Wallmann, Darren Langley, Joe Clapis, Nick Doherty * */ pragma solidity >0.5.0 <0.9.0; // SPDX-License-Identifier: GPL-3.0-only // Represents a minipool's status within the network enum MinipoolStatus { Initialised, // The minipool has been initialised and is awaiting a deposit of user ETH Prelaunch, // The minipool has enough ETH to begin staking and is awaiting launch by the node operator Staking, // The minipool is currently staking Withdrawable, // NO LONGER USED Dissolved // The minipool has been dissolved and its user deposited ETH has been returned to the deposit pool }
/** * . * / \ * |.'.| * |'.'| * ,'| |`. * |,-'-|-'-.| * __|_| | _ _ _____ _ * | ___ \| | | | | | ___ \ | | * | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | | * | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| | * | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | | * \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_| * +---------------------------------------------------+ * | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM 2.0 | * +---------------------------------------------------+ * * Rocket Pool is a first-of-its-kind ETH2 Proof of Stake protocol, designed to be community owned, * decentralised, trustless and compatible with staking in Ethereum 2.0. * * For more information about Rocket Pool, visit https://rocketpool.net * * Authors: David Rugendyke, Jake Pospischil, Kane Wallmann, Darren Langley, Joe Clapis, Nick Doherty * */ pragma solidity >0.5.0 <0.9.0; // SPDX-License-Identifier: GPL-3.0-only // A struct containing all the information on-chain about a specific node struct NodeDetails { bool exists; uint256 registrationTime; string timezoneLocation; bool feeDistributorInitialised; address feeDistributorAddress; uint256 rewardNetwork; uint256 rplStake; uint256 effectiveRPLStake; uint256 minimumRPLStake; uint256 maximumRPLStake; uint256 ethMatched; uint256 ethMatchedLimit; uint256 minipoolCount; uint256 balanceETH; uint256 balanceRETH; uint256 balanceRPL; uint256 balanceOldRPL; uint256 depositCreditBalance; uint256 distributorBalanceUserETH; uint256 distributorBalanceNodeETH; address withdrawalAddress; address pendingWithdrawalAddress; bool smoothingPoolRegistrationState; uint256 smoothingPoolRegistrationChanged; address nodeAddress; }
/** * . * / \ * |.'.| * |'.'| * ,'| |`. * |,-'-|-'-.| * __|_| | _ _ _____ _ * | ___ \| | | | | | ___ \ | | * | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | | * | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| | * | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | | * \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_| * +---------------------------------------------------+ * | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM 2.0 | * +---------------------------------------------------+ * * Rocket Pool is a first-of-its-kind ETH2 Proof of Stake protocol, designed to be community owned, * decentralised, trustless and compatible with staking in Ethereum 2.0. * * For more information about Rocket Pool, visit https://rocketpool.net * * Authors: David Rugendyke, Jake Pospischil, Kane Wallmann, Darren Langley, Joe Clapis, Nick Doherty * */ // SPDX-License-Identifier: GPL-3.0-only pragma solidity >0.5.0 <0.9.0; pragma abicoder v2; import "../../types/NodeDetails.sol"; interface RocketNodeManagerInterface { // Structs struct TimezoneCount { string timezone; uint256 count; } function getNodeCount() external view returns (uint256); function getNodeCountPerTimezone(uint256 offset, uint256 limit) external view returns (TimezoneCount[] memory); function getNodeAt(uint256 _index) external view returns (address); function getNodeExists(address _nodeAddress) external view returns (bool); function getNodeWithdrawalAddress(address _nodeAddress) external view returns (address); function getNodePendingWithdrawalAddress(address _nodeAddress) external view returns (address); function getNodeRPLWithdrawalAddress(address _nodeAddress) external view returns (address); function getNodeRPLWithdrawalAddressIsSet(address _nodeAddress) external view returns (bool); function unsetRPLWithdrawalAddress(address _nodeAddress) external; function setRPLWithdrawalAddress(address _nodeAddress, address _newRPLWithdrawalAddress, bool _confirm) external; function confirmRPLWithdrawalAddress(address _nodeAddress) external; function getNodePendingRPLWithdrawalAddress(address _nodeAddress) external view returns (address); function getNodeTimezoneLocation(address _nodeAddress) external view returns (string memory); function registerNode(string calldata _timezoneLocation) external; function getNodeRegistrationTime(address _nodeAddress) external view returns (uint256); function setTimezoneLocation(string calldata _timezoneLocation) external; function setRewardNetwork(address _nodeAddress, uint256 network) external; function getRewardNetwork(address _nodeAddress) external view returns (uint256); function getFeeDistributorInitialised(address _nodeAddress) external view returns (bool); function initialiseFeeDistributor() external; function getAverageNodeFee(address _nodeAddress) external view returns (uint256); function setSmoothingPoolRegistrationState(bool _state) external; function getSmoothingPoolRegistrationState(address _nodeAddress) external returns (bool); function getSmoothingPoolRegistrationChanged(address _nodeAddress) external returns (uint256); function getSmoothingPoolRegisteredNodeCount(uint256 _offset, uint256 _limit) external view returns (uint256); function getNodeDetails(address _nodeAddress) external view returns (NodeDetails memory); function getNodeAddresses(uint256 _offset, uint256 _limit) external view returns (address[] memory); }
/** * . * / \ * |.'.| * |'.'| * ,'| |`. * |,-'-|-'-.| * __|_| | _ _ _____ _ * | ___ \| | | | | | ___ \ | | * | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | | * | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| | * | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | | * \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_| * +---------------------------------------------------+ * | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM 2.0 | * +---------------------------------------------------+ * * Rocket Pool is a first-of-its-kind ETH2 Proof of Stake protocol, designed to be community owned, * decentralised, trustless and compatible with staking in Ethereum 2.0. * * For more information about Rocket Pool, visit https://rocketpool.net * * Authors: David Rugendyke, Jake Pospischil, Kane Wallmann, Darren Langley, Joe Clapis, Nick Doherty * */ pragma solidity >0.5.0 <0.9.0; // SPDX-License-Identifier: GPL-3.0-only interface RocketDAOProtocolSettingsNodeInterface { function getRegistrationEnabled() external view returns (bool); function getSmoothingPoolRegistrationEnabled() external view returns (bool); function getDepositEnabled() external view returns (bool); function getVacantMinipoolsEnabled() external view returns (bool); function getMinimumPerMinipoolStake() external view returns (uint256); function getMaximumPerMinipoolStake() external view returns (uint256); function getMaximumStakeForVotingPower() external view returns (uint256); }
/** * . * / \ * |.'.| * |'.'| * ,'| |`. * |,-'-|-'-.| * __|_| | _ _ _____ _ * | ___ \| | | | | | ___ \ | | * | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | | * | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| | * | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | | * \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_| * +---------------------------------------------------+ * | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM 2.0 | * +---------------------------------------------------+ * * Rocket Pool is a first-of-its-kind ETH2 Proof of Stake protocol, designed to be community owned, * decentralised, trustless and compatible with staking in Ethereum 2.0. * * For more information about Rocket Pool, visit https://rocketpool.net * * Authors: David Rugendyke, Jake Pospischil, Kane Wallmann, Darren Langley, Joe Clapis, Nick Doherty * */ pragma solidity >0.5.0 <0.9.0; // SPDX-License-Identifier: GPL-3.0-only interface AddressSetStorageInterface { function getCount(bytes32 _key) external view returns (uint); function getItem(bytes32 _key, uint _index) external view returns (address); function getIndexOf(bytes32 _key, address _value) external view returns (int); function addItem(bytes32 _key, address _value) external; function removeItem(bytes32 _key, address _value) external; }
/** * . * / \ * |.'.| * |'.'| * ,'| |`. * |,-'-|-'-.| * __|_| | _ _ _____ _ * | ___ \| | | | | | ___ \ | | * | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | | * | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| | * | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | | * \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_| * +---------------------------------------------------+ * | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM 2.0 | * +---------------------------------------------------+ * * Rocket Pool is a first-of-its-kind ETH2 Proof of Stake protocol, designed to be community owned, * decentralised, trustless and compatible with staking in Ethereum 2.0. * * For more information about Rocket Pool, visit https://rocketpool.net * * Authors: David Rugendyke, Jake Pospischil, Kane Wallmann, Darren Langley, Joe Clapis, Nick Doherty * */ pragma solidity >0.5.0 <0.9.0; // SPDX-License-Identifier: GPL-3.0-only interface RocketNodeDistributorFactoryInterface { function getProxyBytecode() external pure returns (bytes memory); function getProxyAddress(address _nodeAddress) external view returns(address); function createProxy(address _nodeAddress) external; }
/** * . * / \ * |.'.| * |'.'| * ,'| |`. * |,-'-|-'-.| * __|_| | _ _ _____ _ * | ___ \| | | | | | ___ \ | | * | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | | * | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| | * | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | | * \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_| * +---------------------------------------------------+ * | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM 2.0 | * +---------------------------------------------------+ * * Rocket Pool is a first-of-its-kind ETH2 Proof of Stake protocol, designed to be community owned, * decentralised, trustless and compatible with staking in Ethereum 2.0. * * For more information about Rocket Pool, visit https://rocketpool.net * * Authors: David Rugendyke, Jake Pospischil, Kane Wallmann, Darren Langley, Joe Clapis, Nick Doherty * */ pragma solidity >0.5.0 <0.9.0; // SPDX-License-Identifier: GPL-3.0-only // Represents the type of deposits required by a minipool enum MinipoolDeposit { None, // Marks an invalid deposit type Full, // The minipool requires 32 ETH from the node operator, 16 ETH of which will be refinanced from user deposits Half, // The minipool required 16 ETH from the node operator to be matched with 16 ETH from user deposits Empty, // The minipool requires 0 ETH from the node operator to be matched with 32 ETH from user deposits (trusted nodes only) Variable // Indicates this minipool is of the new generation that supports a variable deposit amount }
/** * . * / \ * |.'.| * |'.'| * ,'| |`. * |,-'-|-'-.| * __|_| | _ _ _____ _ * | ___ \| | | | | | ___ \ | | * | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | | * | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| | * | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | | * \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_| * +---------------------------------------------------+ * | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM 2.0 | * +---------------------------------------------------+ * * Rocket Pool is a first-of-its-kind ETH2 Proof of Stake protocol, designed to be community owned, * decentralised, trustless and compatible with staking in Ethereum 2.0. * * For more information about Rocket Pool, visit https://rocketpool.net * * Authors: David Rugendyke, Jake Pospischil, Kane Wallmann, Darren Langley, Joe Clapis, Nick Doherty * */ pragma solidity >0.5.0 <0.9.0; // SPDX-License-Identifier: GPL-3.0-only import "./MinipoolDeposit.sol"; import "./MinipoolStatus.sol"; // A struct containing all the information on-chain about a specific minipool struct MinipoolDetails { bool exists; address minipoolAddress; bytes pubkey; MinipoolStatus status; uint256 statusBlock; uint256 statusTime; bool finalised; MinipoolDeposit depositType; uint256 nodeFee; uint256 nodeDepositBalance; bool nodeDepositAssigned; uint256 userDepositBalance; bool userDepositAssigned; uint256 userDepositAssignedTime; bool useLatestDelegate; address delegate; address previousDelegate; address effectiveDelegate; uint256 penaltyCount; uint256 penaltyRate; address nodeAddress; }
/** * . * / \ * |.'.| * |'.'| * ,'| |`. * |,-'-|-'-.| * __|_| | _ _ _____ _ * | ___ \| | | | | | ___ \ | | * | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | | * | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| | * | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | | * \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_| * +---------------------------------------------------+ * | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM 2.0 | * +---------------------------------------------------+ * * Rocket Pool is a first-of-its-kind ETH2 Proof of Stake protocol, designed to be community owned, * decentralised, trustless and compatible with staking in Ethereum 2.0. * * For more information about Rocket Pool, visit https://rocketpool.net * * Authors: David Rugendyke, Jake Pospischil, Kane Wallmann, Darren Langley, Joe Clapis, Nick Doherty * */ pragma solidity >0.5.0 <0.9.0; // SPDX-License-Identifier: GPL-3.0-only import "../../types/MinipoolDeposit.sol"; import "../../types/MinipoolStatus.sol"; import "../RocketStorageInterface.sol"; interface RocketMinipoolInterface { function version() external view returns (uint8); function initialise(address _nodeAddress) external; function getStatus() external view returns (MinipoolStatus); function getFinalised() external view returns (bool); function getStatusBlock() external view returns (uint256); function getStatusTime() external view returns (uint256); function getScrubVoted(address _member) external view returns (bool); function getDepositType() external view returns (MinipoolDeposit); function getNodeAddress() external view returns (address); function getNodeFee() external view returns (uint256); function getNodeDepositBalance() external view returns (uint256); function getNodeRefundBalance() external view returns (uint256); function getNodeDepositAssigned() external view returns (bool); function getPreLaunchValue() external view returns (uint256); function getNodeTopUpValue() external view returns (uint256); function getVacant() external view returns (bool); function getPreMigrationBalance() external view returns (uint256); function getUserDistributed() external view returns (bool); function getUserDepositBalance() external view returns (uint256); function getUserDepositAssigned() external view returns (bool); function getUserDepositAssignedTime() external view returns (uint256); function getTotalScrubVotes() external view returns (uint256); function calculateNodeShare(uint256 _balance) external view returns (uint256); function calculateUserShare(uint256 _balance) external view returns (uint256); function preDeposit(uint256 _bondingValue, bytes calldata _validatorPubkey, bytes calldata _validatorSignature, bytes32 _depositDataRoot) external payable; function deposit() external payable; function userDeposit() external payable; function distributeBalance(bool _rewardsOnly) external; function beginUserDistribute() external; function userDistributeAllowed() external view returns (bool); function refund() external; function slash() external; function finalise() external; function canStake() external view returns (bool); function canPromote() external view returns (bool); function stake(bytes calldata _validatorSignature, bytes32 _depositDataRoot) external; function prepareVacancy(uint256 _bondAmount, uint256 _currentBalance) external; function promote() external; function dissolve() external; function close() external; function voteScrub() external; function reduceBondAmount() external; }
/** * . * / \ * |.'.| * |'.'| * ,'| |`. * |,-'-|-'-.| * __|_| | _ _ _____ _ * | ___ \| | | | | | ___ \ | | * | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | | * | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| | * | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | | * \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_| * +---------------------------------------------------+ * | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM 2.0 | * +---------------------------------------------------+ * * Rocket Pool is a first-of-its-kind ETH2 Proof of Stake protocol, designed to be community owned, * decentralised, trustless and compatible with staking in Ethereum 2.0. * * For more information about Rocket Pool, visit https://rocketpool.net * * Authors: David Rugendyke, Jake Pospischil, Kane Wallmann, Darren Langley, Joe Clapis, Nick Doherty * */ pragma solidity >0.5.0 <0.9.0; pragma abicoder v2; // SPDX-License-Identifier: GPL-3.0-only import "../../types/MinipoolDeposit.sol"; import "../../types/MinipoolDetails.sol"; import "./RocketMinipoolInterface.sol"; interface RocketMinipoolManagerInterface { function getMinipoolCount() external view returns (uint256); function getStakingMinipoolCount() external view returns (uint256); function getFinalisedMinipoolCount() external view returns (uint256); function getActiveMinipoolCount() external view returns (uint256); function getMinipoolRPLSlashed(address _minipoolAddress) external view returns (bool); function getMinipoolCountPerStatus(uint256 offset, uint256 limit) external view returns (uint256, uint256, uint256, uint256, uint256); function getPrelaunchMinipools(uint256 offset, uint256 limit) external view returns (address[] memory); function getMinipoolAt(uint256 _index) external view returns (address); function getNodeMinipoolCount(address _nodeAddress) external view returns (uint256); function getNodeActiveMinipoolCount(address _nodeAddress) external view returns (uint256); function getNodeFinalisedMinipoolCount(address _nodeAddress) external view returns (uint256); function getNodeStakingMinipoolCount(address _nodeAddress) external view returns (uint256); function getNodeStakingMinipoolCountBySize(address _nodeAddress, uint256 _depositSize) external view returns (uint256); function getNodeMinipoolAt(address _nodeAddress, uint256 _index) external view returns (address); function getNodeValidatingMinipoolCount(address _nodeAddress) external view returns (uint256); function getNodeValidatingMinipoolAt(address _nodeAddress, uint256 _index) external view returns (address); function getMinipoolByPubkey(bytes calldata _pubkey) external view returns (address); function getMinipoolExists(address _minipoolAddress) external view returns (bool); function getMinipoolDestroyed(address _minipoolAddress) external view returns (bool); function getMinipoolPubkey(address _minipoolAddress) external view returns (bytes memory); function updateNodeStakingMinipoolCount(uint256 _previousBond, uint256 _newBond, uint256 _previousFee, uint256 _newFee) external; function getMinipoolWithdrawalCredentials(address _minipoolAddress) external pure returns (bytes memory); function createMinipool(address _nodeAddress, uint256 _salt) external returns (RocketMinipoolInterface); function createVacantMinipool(address _nodeAddress, uint256 _salt, bytes calldata _validatorPubkey, uint256 _bondAmount, uint256 _currentBalance) external returns (RocketMinipoolInterface); function removeVacantMinipool() external; function getVacantMinipoolCount() external view returns (uint256); function getVacantMinipoolAt(uint256 _index) external view returns (address); function destroyMinipool() external; function incrementNodeStakingMinipoolCount(address _nodeAddress) external; function decrementNodeStakingMinipoolCount(address _nodeAddress) external; function tryDistribute(address _nodeAddress) external; function incrementNodeFinalisedMinipoolCount(address _nodeAddress) external; function setMinipoolPubkey(bytes calldata _pubkey) external; function getMinipoolDepositType(address _minipoolAddress) external view returns (MinipoolDeposit); }
/** * . * / \ * |.'.| * |'.'| * ,'| |`. * |,-'-|-'-.| * __|_| | _ _ _____ _ * | ___ \| | | | | | ___ \ | | * | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | | * | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| | * | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | | * \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_| * +---------------------------------------------------+ * | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM 2.0 | * +---------------------------------------------------+ * * Rocket Pool is a first-of-its-kind ETH2 Proof of Stake protocol, designed to be community owned, * decentralised, trustless and compatible with staking in Ethereum 2.0. * * For more information about Rocket Pool, visit https://rocketpool.net * * Authors: David Rugendyke, Jake Pospischil, Kane Wallmann, Darren Langley, Joe Clapis, Nick Doherty * */ pragma solidity >0.5.0 <0.9.0; // SPDX-License-Identifier: GPL-3.0-only interface RocketNodeDistributorInterface { function getNodeShare() external view returns (uint256); function getUserShare() external view returns (uint256); function distribute() external; }
/** * . * / \ * |.'.| * |'.'| * ,'| |`. * |,-'-|-'-.| * __|_| | _ _ _____ _ * | ___ \| | | | | | ___ \ | | * | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | | * | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| | * | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | | * \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_| * +---------------------------------------------------+ * | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM 2.0 | * +---------------------------------------------------+ * * Rocket Pool is a first-of-its-kind ETH2 Proof of Stake protocol, designed to be community owned, * decentralised, trustless and compatible with staking in Ethereum 2.0. * * For more information about Rocket Pool, visit https://rocketpool.net * * Authors: David Rugendyke, Jake Pospischil, Kane Wallmann, Darren Langley, Joe Clapis, Nick Doherty * */ // SPDX-License-Identifier: GPL-3.0-only pragma solidity >0.5.0 <0.9.0; interface RocketDAONodeTrustedSettingsRewardsInterface { function getNetworkEnabled(uint256 _network) external view returns (bool); }
/** * . * / \ * |.'.| * |'.'| * ,'| |`. * |,-'-|-'-.| * __|_| | _ _ _____ _ * | ___ \| | | | | | ___ \ | | * | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | | * | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| | * | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | | * \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_| * +---------------------------------------------------+ * | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM 2.0 | * +---------------------------------------------------+ * * Rocket Pool is a first-of-its-kind ETH2 Proof of Stake protocol, designed to be community owned, * decentralised, trustless and compatible with staking in Ethereum 2.0. * * For more information about Rocket Pool, visit https://rocketpool.net * * Authors: David Rugendyke, Jake Pospischil, Kane Wallmann, Darren Langley, Joe Clapis, Nick Doherty * */ // SPDX-License-Identifier: GPL-3.0-only pragma solidity >0.5.0 <0.9.0; interface RocketDAOProtocolSettingsRewardsInterface { function setSettingRewardsClaimers(uint256 _trustedNodePercent, uint256 _protocolPercent, uint256 _nodePercent) external; function getRewardsClaimerPerc(string memory _contractName) external view returns (uint256); function getRewardsClaimersPerc() external view returns (uint256 _trustedNodePercent, uint256 _protocolPercent, uint256 _nodePercent); function getRewardsClaimersTrustedNodePerc() external view returns (uint256); function getRewardsClaimersProtocolPerc() external view returns (uint256); function getRewardsClaimersNodePerc() external view returns (uint256); function getRewardsClaimersTimeUpdated() external view returns (uint256); function getRewardsClaimIntervalPeriods() external view returns (uint256); function getRewardsClaimIntervalTime() external view returns (uint256); }
/** * . * / \ * |.'.| * |'.'| * ,'| |`. * |,-'-|-'-.| * __|_| | _ _ _____ _ * | ___ \| | | | | | ___ \ | | * | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | | * | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| | * | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | | * \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_| * +---------------------------------------------------+ * | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM 2.0 | * +---------------------------------------------------+ * * Rocket Pool is a first-of-its-kind ETH2 Proof of Stake protocol, designed to be community owned, * decentralised, trustless and compatible with staking in Ethereum 2.0. * * For more information about Rocket Pool, visit https://rocketpool.net * * Authors: David Rugendyke, Jake Pospischil, Kane Wallmann, Darren Langley, Joe Clapis, Nick Doherty * */ // SPDX-License-Identifier: GPL-3.0-only pragma solidity >0.5.0 <0.9.0; interface RocketNodeStakingInterface { function getTotalRPLStake() external view returns (uint256); function getNodeRPLStake(address _nodeAddress) external view returns (uint256); function getNodeETHMatched(address _nodeAddress) external view returns (uint256); function getNodeETHProvided(address _nodeAddress) external view returns (uint256); function getNodeETHCollateralisationRatio(address _nodeAddress) external view returns (uint256); function getNodeRPLStakedTime(address _nodeAddress) external view returns (uint256); function getNodeEffectiveRPLStake(address _nodeAddress) external view returns (uint256); function getNodeMinimumRPLStake(address _nodeAddress) external view returns (uint256); function getNodeMaximumRPLStake(address _nodeAddress) external view returns (uint256); function getNodeETHMatchedLimit(address _nodeAddress) external view returns (uint256); function getRPLLockingAllowed(address _nodeAddress) external view returns (bool); function stakeRPL(uint256 _amount) external; function stakeRPLFor(address _nodeAddress, uint256 _amount) external; function setRPLLockingAllowed(address _nodeAddress, bool _allowed) external; function setStakeRPLForAllowed(address _caller, bool _allowed) external; function setStakeRPLForAllowed(address _nodeAddress, address _caller, bool _allowed) external; function getNodeRPLLocked(address _nodeAddress) external view returns (uint256); function lockRPL(address _nodeAddress, uint256 _amount) external; function unlockRPL(address _nodeAddress, uint256 _amount) external; function transferRPL(address _from, address _to, uint256 _amount) external; function withdrawRPL(uint256 _amount) external; function withdrawRPL(address _nodeAddress, uint256 _amount) external; function slashRPL(address _nodeAddress, uint256 _ethSlashAmount) external; }
/** * . * / \ * |.'.| * |'.'| * ,'| |`. * |,-'-|-'-.| * __|_| | _ _ _____ _ * | ___ \| | | | | | ___ \ | | * | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | | * | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| | * | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | | * \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_| * +---------------------------------------------------+ * | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM 2.0 | * +---------------------------------------------------+ * * Rocket Pool is a first-of-its-kind ETH2 Proof of Stake protocol, designed to be community owned, * decentralised, trustless and compatible with staking in Ethereum 2.0. * * For more information about Rocket Pool, visit https://rocketpool.net * * Authors: David Rugendyke, Jake Pospischil, Kane Wallmann, Darren Langley, Joe Clapis, Nick Doherty * */ pragma solidity >0.5.0 <0.9.0; // SPDX-License-Identifier: GPL-3.0-only import "../../types/MinipoolDeposit.sol"; interface RocketNodeDepositInterface { function getNodeDepositCredit(address _nodeAddress) external view returns (uint256); function getNodeEthBalance(address _nodeAddress) external view returns (uint256); function getNodeCreditAndBalance(address _nodeAddress) external view returns (uint256); function getNodeUsableCreditAndBalance(address _nodeAddress) external view returns (uint256); function getNodeUsableCredit(address _nodeAddress) external view returns (uint256); function increaseDepositCreditBalance(address _nodeOperator, uint256 _amount) external; function depositEthFor(address _nodeAddress) external payable; function withdrawEth(address _nodeAddress, uint256 _amount) external; function deposit(uint256 _depositAmount, uint256 _minimumNodeFee, bytes calldata _validatorPubkey, bytes calldata _validatorSignature, bytes32 _depositDataRoot, uint256 _salt, address _expectedMinipoolAddress) external payable; function depositWithCredit(uint256 _depositAmount, uint256 _minimumNodeFee, bytes calldata _validatorPubkey, bytes calldata _validatorSignature, bytes32 _depositDataRoot, uint256 _salt, address _expectedMinipoolAddress) external payable; function isValidDepositAmount(uint256 _amount) external pure returns (bool); function getDepositAmounts() external pure returns (uint256[] memory); function createVacantMinipool(uint256 _bondAmount, uint256 _minimumNodeFee, bytes calldata _validatorPubkey, uint256 _salt, address _expectedMinipoolAddress, uint256 _currentBalance) external; function increaseEthMatched(address _nodeAddress, uint256 _amount) external; }
/** * . * / \ * |.'.| * |'.'| * ,'| |`. * |,-'-|-'-.| * __|_| | _ _ _____ _ * | ___ \| | | | | | ___ \ | | * | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | | * | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| | * | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | | * \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_| * +---------------------------------------------------+ * | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM 2.0 | * +---------------------------------------------------+ * * Rocket Pool is a first-of-its-kind ETH2 Proof of Stake protocol, designed to be community owned, * decentralised, trustless and compatible with staking in Ethereum 2.0. * * For more information about Rocket Pool, visit https://rocketpool.net * * Authors: David Rugendyke, Jake Pospischil, Kane Wallmann, Darren Langley, Joe Clapis, Nick Doherty * */ pragma solidity >0.5.0 <0.9.0; // SPDX-License-Identifier: GPL-3.0-only import "../../../../types/MinipoolDeposit.sol"; interface RocketDAOProtocolSettingsMinipoolInterface { function getLaunchBalance() external view returns (uint256); function getPreLaunchValue() external pure returns (uint256); function getDepositUserAmount(MinipoolDeposit _depositType) external view returns (uint256); function getFullDepositUserAmount() external view returns (uint256); function getHalfDepositUserAmount() external view returns (uint256); function getVariableDepositAmount() external view returns (uint256); function getSubmitWithdrawableEnabled() external view returns (bool); function getBondReductionEnabled() external view returns (bool); function getLaunchTimeout() external view returns (uint256); function getMaximumCount() external view returns (uint256); function isWithinUserDistributeWindow(uint256 _time) external view returns (bool); function hasUserDistributeWindowPassed(uint256 _time) external view returns (bool); function getUserDistributeWindowStart() external view returns (uint256); function getUserDistributeWindowLength() external view returns (uint256); }
/** * . * / \ * |.'.| * |'.'| * ,'| |`. * |,-'-|-'-.| * __|_| | _ _ _____ _ * | ___ \| | | | | | ___ \ | | * | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | | * | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| | * | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | | * \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_| * +---------------------------------------------------+ * | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM 2.0 | * +---------------------------------------------------+ * * Rocket Pool is a first-of-its-kind ETH2 Proof of Stake protocol, designed to be community owned, * decentralised, trustless and compatible with staking in Ethereum 2.0. * * For more information about Rocket Pool, visit https://rocketpool.net * * Authors: David Rugendyke, Jake Pospischil, Kane Wallmann, Darren Langley, Joe Clapis, Nick Doherty * */ // SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity >0.5.0 <0.9.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); }
/** * . * / \ * |.'.| * |'.'| * ,'| |`. * |,-'-|-'-.| * __|_| | _ _ _____ _ * | ___ \| | | | | | ___ \ | | * | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | | * | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| | * | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | | * \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_| * +---------------------------------------------------+ * | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM 2.0 | * +---------------------------------------------------+ * * Rocket Pool is a first-of-its-kind ETH2 Proof of Stake protocol, designed to be community owned, * decentralised, trustless and compatible with staking in Ethereum 2.0. * * For more information about Rocket Pool, visit https://rocketpool.net * * Authors: David Rugendyke, Jake Pospischil, Kane Wallmann, Darren Langley, Joe Clapis, Nick Doherty * */ // SPDX-License-Identifier: GPL-3.0-only pragma solidity >0.5.0 <0.9.0; struct Checkpoint224 { uint32 _block; uint224 _value; } /// @notice Accounting for snapshotting of values based on block numbers interface RocketNetworkSnapshotsInterface { function push(bytes32 _key, uint224 _value) external; function length(bytes32 _key) external view returns (uint256); function latest(bytes32 _key) external view returns (bool, uint32, uint224); function latestBlock(bytes32 _key) external view returns (uint32); function latestValue(bytes32 _key) external view returns (uint224); function lookup(bytes32 _key, uint32 _block) external view returns (uint224); function lookupRecent(bytes32 _key, uint32 _block, uint256 _recency) external view returns (uint224); }
{ "optimizer": { "enabled": true, "runs": 15000 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
[{"inputs":[{"internalType":"contract RocketStorageInterface","name":"_rocketStorageAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"node","type":"address"},{"indexed":true,"internalType":"address","name":"withdrawalAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"NodeRPLWithdrawalAddressSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"node","type":"address"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"NodeRPLWithdrawalAddressUnset","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"node","type":"address"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"NodeRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"node","type":"address"},{"indexed":false,"internalType":"uint256","name":"network","type":"uint256"}],"name":"NodeRewardNetworkChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"node","type":"address"},{"indexed":false,"internalType":"bool","name":"state","type":"bool"}],"name":"NodeSmoothingPoolStateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"node","type":"address"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"NodeTimezoneLocationSet","type":"event"},{"inputs":[{"internalType":"address","name":"_nodeAddress","type":"address"}],"name":"confirmRPLWithdrawalAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_nodeAddress","type":"address"}],"name":"getAverageNodeFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_nodeAddress","type":"address"}],"name":"getFeeDistributorInitialised","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_offset","type":"uint256"},{"internalType":"uint256","name":"_limit","type":"uint256"}],"name":"getNodeAddresses","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getNodeAt","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNodeCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_offset","type":"uint256"},{"internalType":"uint256","name":"_limit","type":"uint256"}],"name":"getNodeCountPerTimezone","outputs":[{"components":[{"internalType":"string","name":"timezone","type":"string"},{"internalType":"uint256","name":"count","type":"uint256"}],"internalType":"struct RocketNodeManagerInterface.TimezoneCount[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_nodeAddress","type":"address"}],"name":"getNodeDetails","outputs":[{"components":[{"internalType":"bool","name":"exists","type":"bool"},{"internalType":"uint256","name":"registrationTime","type":"uint256"},{"internalType":"string","name":"timezoneLocation","type":"string"},{"internalType":"bool","name":"feeDistributorInitialised","type":"bool"},{"internalType":"address","name":"feeDistributorAddress","type":"address"},{"internalType":"uint256","name":"rewardNetwork","type":"uint256"},{"internalType":"uint256","name":"rplStake","type":"uint256"},{"internalType":"uint256","name":"effectiveRPLStake","type":"uint256"},{"internalType":"uint256","name":"minimumRPLStake","type":"uint256"},{"internalType":"uint256","name":"maximumRPLStake","type":"uint256"},{"internalType":"uint256","name":"ethMatched","type":"uint256"},{"internalType":"uint256","name":"ethMatchedLimit","type":"uint256"},{"internalType":"uint256","name":"minipoolCount","type":"uint256"},{"internalType":"uint256","name":"balanceETH","type":"uint256"},{"internalType":"uint256","name":"balanceRETH","type":"uint256"},{"internalType":"uint256","name":"balanceRPL","type":"uint256"},{"internalType":"uint256","name":"balanceOldRPL","type":"uint256"},{"internalType":"uint256","name":"depositCreditBalance","type":"uint256"},{"internalType":"uint256","name":"distributorBalanceUserETH","type":"uint256"},{"internalType":"uint256","name":"distributorBalanceNodeETH","type":"uint256"},{"internalType":"address","name":"withdrawalAddress","type":"address"},{"internalType":"address","name":"pendingWithdrawalAddress","type":"address"},{"internalType":"bool","name":"smoothingPoolRegistrationState","type":"bool"},{"internalType":"uint256","name":"smoothingPoolRegistrationChanged","type":"uint256"},{"internalType":"address","name":"nodeAddress","type":"address"}],"internalType":"struct NodeDetails","name":"nodeDetails","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_nodeAddress","type":"address"}],"name":"getNodeExists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_nodeAddress","type":"address"}],"name":"getNodePendingRPLWithdrawalAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_nodeAddress","type":"address"}],"name":"getNodePendingWithdrawalAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_nodeAddress","type":"address"}],"name":"getNodeRPLWithdrawalAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_nodeAddress","type":"address"}],"name":"getNodeRPLWithdrawalAddressIsSet","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_nodeAddress","type":"address"}],"name":"getNodeRegistrationTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_nodeAddress","type":"address"}],"name":"getNodeTimezoneLocation","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_nodeAddress","type":"address"}],"name":"getNodeWithdrawalAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_nodeAddress","type":"address"}],"name":"getRewardNetwork","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_offset","type":"uint256"},{"internalType":"uint256","name":"_limit","type":"uint256"}],"name":"getSmoothingPoolRegisteredNodeCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_nodeAddress","type":"address"}],"name":"getSmoothingPoolRegistrationChanged","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_nodeAddress","type":"address"}],"name":"getSmoothingPoolRegistrationState","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialiseFeeDistributor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_timezoneLocation","type":"string"}],"name":"registerNode","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_nodeAddress","type":"address"},{"internalType":"address","name":"_newRPLWithdrawalAddress","type":"address"},{"internalType":"bool","name":"_confirm","type":"bool"}],"name":"setRPLWithdrawalAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_nodeAddress","type":"address"},{"internalType":"uint256","name":"_network","type":"uint256"}],"name":"setRewardNetwork","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_state","type":"bool"}],"name":"setSmoothingPoolRegistrationState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_timezoneLocation","type":"string"}],"name":"setTimezoneLocation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_nodeAddress","type":"address"}],"name":"unsetRPLWithdrawalAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405260008054610100600160a81b03191690553480156200002257600080fd5b50604051620052d9380380620052d983398101604081905262000045916200007a565b6000805460ff196001600160a01b0390931661010002929092166001600160a81b0319909216919091176004179055620000ac565b6000602082840312156200008d57600080fd5b81516001600160a01b0381168114620000a557600080fd5b9392505050565b61521d80620000bc6000396000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c806365d4176f116100f9578063b71f0c7c11610097578063d565f27611610071578063d565f276146103f8578063e667d8281461040b578063f5b17b421461041e578063fd4125131461043157600080fd5b8063b71f0c7c146103b2578063ba75d806146103c5578063bafb3581146103d857600080fd5b8063a4cef9dd116100d3578063a4cef9dd14610359578063a7e6e8b31461036c578063b018f0261461037f578063b715a1aa1461039f57600080fd5b806365d4176f14610310578063927ece4f1461033357806399283f8b1461034657600080fd5b80633a643648116101665780634d99f633116101405780634d99f633146102c357806354fd4d50146102d65780635b49ff62146102f557806364908a861461030857600080fd5b80633a6436481461028a578063414dd1d21461029d57806343f88981146102b057600080fd5b806329554540116101a2578063295545401461022f5780632a7968eb1461024f5780632d7f21d01461026257806339bf397e1461028257600080fd5b806302d8a732146101c95780631ac3c0a8146101ef57806327c6f43e1461021a575b600080fd5b6101dc6101d73660046149b0565b610444565b6040519081526020015b60405180910390f35b6102026101fd3660046149b0565b6105bf565b6040516001600160a01b0390911681526020016101e6565b61022d6102283660046149cd565b61065a565b005b61024261023d366004614a3f565b610e54565b6040516101e69190614ab1565b61022d61025d3660046149b0565b6111ff565b610275610270366004614a3f565b6113db565b6040516101e69190614b45565b6101dc6115c7565b61022d6102983660046149b0565b6116c7565b6101dc6102ab3660046149b0565b611899565b6101dc6102be3660046149b0565b611ebf565b6101dc6102d13660046149b0565b611fc2565b6000546102e39060ff1681565b60405160ff90911681526020016101e6565b6102026103033660046149b0565b612016565b61022d6120a5565b61032361031e3660046149b0565b61251e565b60405190151581526020016101e6565b6103236103413660046149b0565b61256f565b61022d610354366004614ba0565b61264a565b6103236103673660046149b0565b612b38565b61022d61037a3660046149cd565b612b89565b61039261038d3660046149b0565b612dfa565b6040516101e69190614bbd565b6101dc6103ad366004614a3f565b612e49565b6102026103c03660046149b0565b612fda565b6102026103d3366004614bd0565b6130cb565b6103eb6103e63660046149b0565b6131a6565b6040516101e69190614be9565b61022d610406366004614d83565b613d05565b6103236104193660046149b0565b614089565b61022d61042c366004614daf565b6140ed565b61020261043f3660046149b0565b6143a6565b6040517f6e6f64652e65786973747300000000000000000000000000000000000000000060208201526bffffffffffffffffffffffff19606083901b16602b82015260009082906104ae90603f015b604051602081830303815290604052805190602001206143f8565b6104ff5760405162461bcd60e51b815260206004820152600c60248201527f496e76616c6964206e6f6465000000000000000000000000000000000000000060448201526064015b60405180910390fd5b6105b88360405160200161059d91907f726577617264732e706f6f6c2e636c61696d2e636f6e74726163742e7265676981527f7374657265642e74696d6500000000000000000000000000000000000000000060208201527f726f636b6574436c61696d4e6f64650000000000000000000000000000000000602b82015260609190911b6bffffffffffffffffffffffff1916603a820152604e0190565b60405160208183030381529060405280519060200120614483565b9392505050565b60006106548260405160200161063991907f6e6f64652e70656e64696e672e72706c2e7769746864726177616c2e6164647281527f6573730000000000000000000000000000000000000000000000000000000000602082015260609190911b6bffffffffffffffffffffffff1916602382015260370190565b6040516020818303038152906040528051906020012061450e565b92915050565b6040518060400160405280601181526020017f726f636b65744e6f64654d616e61676572000000000000000000000000000000815250306106a5826040516020016106399190614dfa565b6001600160a01b0316816001600160a01b0316146107055760405162461bcd60e51b815260206004820152601c60248201527f496e76616c6964206f72206f7574646174656420636f6e74726163740000000060448201526064016104f6565b60006107456040518060400160405280601d81526020017f726f636b657444414f50726f746f636f6c53657474696e67734e6f646500000081525061455d565b905060006107876040518060400160405280601181526020017f6164647265737353657453746f7261676500000000000000000000000000000081525061455d565b905060006107c96040518060400160405280601681526020017f726f636b65744e6574776f726b536e617073686f74730000000000000000000081525061455d565b9050826001600160a01b03166387b1bb116040518163ffffffff1660e01b8152600401602060405180830381865afa158015610809573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061082d9190614e3f565b61089f5760405162461bcd60e51b815260206004820152603560248201527f526f636b657420506f6f6c206e6f646520726567697374726174696f6e73206160448201527f72652063757272656e746c792064697361626c6564000000000000000000000060648201526084016104f6565b60048610156108f05760405162461bcd60e51b815260206004820181905260248201527f5468652074696d657a6f6e65206c6f636174696f6e20697320696e76616c696460448201526064016104f6565b6040517f6e6f64652e65786973747300000000000000000000000000000000000000000060208201526bffffffffffffffffffffffff193360601b16602b82015261095690603f015b6040516020818303038152906040528051906020012060016145cc565b6040517f6e6f64652e766f74696e672e656e61626c65640000000000000000000000000060208201526bffffffffffffffffffffffff193360601b1660338201526109a390604701610939565b6040517f6e6f64652e74696d657a6f6e652e6c6f636174696f6e0000000000000000000060208201526bffffffffffffffffffffffff193360601b166036820152610a3d90604a016040516020818303038152906040528051906020012088888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061465492505050565b6040517f6e6f6465732e696e6465780000000000000000000000000000000000000000006020820152600090602b0160408051808303601f190181529082905280516020909101207f889271660000000000000000000000000000000000000000000000000000000082526004820181905233602483015291506001600160a01b03841690638892716690604401600060405180830381600087803b158015610ae557600080fd5b505af1158015610af9573d6000803e3d6000fd5b50505050610b06336146a3565b604080517f726577617264732e706f6f6c2e636c61696d2e636f6e74726163742e7265676960208201527f7374657265642e74696d65000000000000000000000000000000000000000000918101919091527f726f636b6574436c61696d4e6f64650000000000000000000000000000000000604b8201526bffffffffffffffffffffffff193360601b16605a820152610bb990606e01604051602081830303815290604052805190602001204261472e565b816001600160a01b0316635ba59649604051602001610bfb907f6e6f64652e636f756e74000000000000000000000000000000000000000000008152600a0190565b60408051601f198184030181529082905280516020909101207fc9d6fee900000000000000000000000000000000000000000000000000000000825260048201859052906001600160a01b0387169063c9d6fee990602401602060405180830381865afa158015610c70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c949190614e5c565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092527bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166024820152604401600060405180830381600087803b158015610d0857600080fd5b505af1158015610d1c573d6000803e3d6000fd5b50506040517f6e6f64652e64656c65676174650000000000000000000000000000000000000060208201526bffffffffffffffffffffffff193360601b16602d8201526001600160a01b0385169250635ba59649915060410160408051808303601f1901815290829052805160209091012060e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016825260048201527bffffffffffffffffffffffffffffffffffffffffffffffffffffffff33166024820152604401600060405180830381600087803b158015610dfd57600080fd5b505af1158015610e11573d6000803e3d6000fd5b50506040514281523392507ff773bca07d020a1bc1fdd45ea3db573da547dd27180143afaf075c158a847594915060200160405180910390a25050505050505050565b60606000610e966040518060400160405280601181526020017f6164647265737353657453746f7261676500000000000000000000000000000081525061455d565b90506000604051602001610ecd907f6e6f6465732e696e6465780000000000000000000000000000000000000000008152600b0190565b60408051601f198184030181529082905280516020909101207fc9d6fee90000000000000000000000000000000000000000000000000000000082526004820181905291506000906001600160a01b0384169063c9d6fee990602401602060405180830381865afa158015610f46573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6a9190614e5c565b90506000610f788688614ea4565b905081811180610f86575085155b15610f8e5750805b6000610f9a8883614eb7565b67ffffffffffffffff811115610fb257610fb2614eca565b604051908082528060200260200182016040528015610ff857816020015b604080518082019091526060815260006020820152815260200190600190039081610fd05790505b5090506000885b838110156111f1576040517ff3358a3a00000000000000000000000000000000000000000000000000000000815260048101879052602481018290526000906001600160a01b0389169063f3358a3a90604401602060405180830381865afa15801561106f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110939190614ef9565b6040517f6e6f64652e74696d657a6f6e652e6c6f636174696f6e0000000000000000000060208201526bffffffffffffffffffffffff19606083901b1660368201529091506000906110fe90604a015b60405160208183030381529060405280519060200120614783565b90506000805b8581101561118557828051906020012087828151811061112657611126614f16565b6020026020010151600001518051906020012003611175576001915086818151811061115457611154614f16565b6020026020010151602001805180919061116d90614f45565b905250611185565b61117e81614f45565b9050611104565b50806111dd578186868151811061119e5761119e614f16565b60200260200101516000018190525060018686815181106111c1576111c1614f16565b6020908102919091018101510152846111d981614f45565b9550505b505050806111ea90614f45565b9050610fff565b508152979650505050505050565b6040517f6e6f64652e65786973747300000000000000000000000000000000000000000060208201526bffffffffffffffffffffffff19606083901b16602b820152819061124f90603f01610493565b61129b5760405162461bcd60e51b815260206004820152600c60248201527f496e76616c6964206e6f6465000000000000000000000000000000000000000060448201526064016104f6565b6040517f6e6f64652e72706c2e7769746864726177616c2e61646472657373000000000060208201526bffffffffffffffffffffffff19606084901b16603b820152600090604f01604051602081830303815290604052805190602001209050336001600160a01b031661130e8261450e565b6001600160a01b03161461138a5760405162461bcd60e51b815260206004820152603b60248201527f4f6e6c7920612074782066726f6d2061206e6f646527732052504c207769746860448201527f64726177616c20616464726573732063616e20756e736574206974000000000060648201526084016104f6565b61139381614813565b826001600160a01b03167fb62e03dab231209df2b46d49d4aa960deab93ff886a706653b5fc6b7ab57073f426040516113ce91815260200190565b60405180910390a2505050565b6060600061141d6040518060400160405280601181526020017f6164647265737353657453746f7261676500000000000000000000000000000081525061455d565b90506000604051602001611454907f6e6f6465732e696e6465780000000000000000000000000000000000000000008152600b0190565b60405160208183030381529060405280519060200120905060006114766115c7565b905060006114848688614ea4565b905081811180611492575085155b1561149a5750805b60006114a68883614eb7565b67ffffffffffffffff8111156114be576114be614eca565b6040519080825280602002602001820160405280156114e7578160200160208202803683370190505b5090506000885b838110156111f1576040517ff3358a3a00000000000000000000000000000000000000000000000000000000815260048101879052602481018290526001600160a01b0388169063f3358a3a90604401602060405180830381865afa15801561155b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061157f9190614ef9565b83838151811061159157611591614f16565b6001600160a01b0390921660209283029190910190910152816115b381614f45565b925050806115c090614f45565b90506114ee565b6000806116086040518060400160405280601181526020017f6164647265737353657453746f7261676500000000000000000000000000000081525061455d565b9050806001600160a01b031663c9d6fee960405160200161164c907f6e6f6465732e696e6465780000000000000000000000000000000000000000008152600b0190565b604051602081830303815290604052805190602001206040518263ffffffff1660e01b815260040161168091815260200190565b602060405180830381865afa15801561169d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116c19190614e5c565b91505090565b6040517f6e6f64652e65786973747300000000000000000000000000000000000000000060208201526bffffffffffffffffffffffff19606083901b16602b820152819061171790603f01610493565b6117635760405162461bcd60e51b815260206004820152600c60248201527f496e76616c6964206e6f6465000000000000000000000000000000000000000060448201526064016104f6565b6000826040516020016117da91907f6e6f64652e70656e64696e672e72706c2e7769746864726177616c2e6164647281527f6573730000000000000000000000000000000000000000000000000000000000602082015260609190911b6bffffffffffffffffffffffff1916602382015260370190565b604051602081830303815290604052805190602001209050336001600160a01b03166118058261450e565b6001600160a01b0316146118815760405162461bcd60e51b815260206004820152603e60248201527f436f6e6669726d6174696f6e206d75737420636f6d652066726f6d207468652060448201527f70656e64696e672052504c207769746864726177616c2061646472657373000060648201526084016104f6565b61188a81614813565b611894833361488a565b505050565b6000806118da6040518060400160405280601581526020017f726f636b65744d696e69706f6f6c4d616e61676572000000000000000000000081525061455d565b9050600061191c6040518060400160405280601181526020017f726f636b65744e6f64654465706f73697400000000000000000000000000000081525061455d565b905060006119416040518060600160405280602181526020016151a46021913961455d565b90506000826001600160a01b0316639bed5a456040518163ffffffff1660e01b8152600401600060405180830381865afa158015611983573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526119ab9190810190614fae565b90506000815167ffffffffffffffff8111156119c9576119c9614eca565b6040519080825280602002602001820160405280156119f2578160200160208202803683370190505b5090506000825167ffffffffffffffff811115611a1157611a11614eca565b604051908082528060200260200182016040528015611a3a578160200160208202803683370190505b5090506000806000866001600160a01b03166308e50d386040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aa49190614e5c565b905060005b8651811015611ba357896001600160a01b031663240eb3308d898481518110611ad457611ad4614f16565b60200260200101516040518363ffffffff1660e01b8152600401611b0d9291906001600160a01b03929092168252602082015260400190565b602060405180830381865afa158015611b2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b4e9190614e5c565b858281518110611b6057611b60614f16565b602002602001018181525050848181518110611b7e57611b7e614f16565b602002602001015183611b919190614ea4565b9250611b9c81614f45565b9050611aa9565b5081600003611bbd575060009a9950505050505050505050565b60005b8651811015611c6757848181518110611bdb57611bdb614f16565b6020026020010151878281518110611bf557611bf5614f16565b602002602001015183611c089190614eb7565b611c129190615054565b868281518110611c2457611c24614f16565b602002602001018181525050858181518110611c4257611c42614f16565b602002602001015184611c559190614ea4565b9350611c6081614f45565b9050611bc0565b5060005b8651811015611cd95783670de0b6b3a7640000878381518110611c9057611c90614f16565b6020026020010151611ca29190615054565b611cac919061506b565b868281518110611cbe57611cbe614f16565b6020908102919091010152611cd281614f45565b9050611c6b565b506000805b8751811015611e9c576000868281518110611cfb57611cfb614f16565b60200260200101511115611e8c576000888281518110611d1d57611d1d614f16565b602002602001015167de0b6b3a7640000003611d9f578d604051602001611d8291907f6e6f64652e617665726167652e6665652e6e756d657261746f72000000000000815260609190911b6bffffffffffffffffffffffff1916601a820152602e0190565b604051602081830303815290604052805190602001209050611e27565b8d898381518110611db257611db2614f16565b6020026020010151604051602001611e0e9291907f6e6f64652e617665726167652e6665652e6e756d657261746f72000000000000815260609290921b6bffffffffffffffffffffffff1916601a830152602e820152604e0190565b6040516020818303038152906040528051906020012090505b6000611e3282614483565b9050878381518110611e4657611e46614f16565b6020026020010151898481518110611e6057611e60614f16565b602002602001015182611e739190615054565b611e7d919061506b565b611e879085614ea4565b935050505b611e9581614f45565b9050611cde565b50611eaf670de0b6b3a76400008261506b565b9c9b505050505050505050505050565b60006040518060400160405280601181526020017f726f636b65744e6f64654d616e6167657200000000000000000000000000000081525030611f0c826040516020016106399190614dfa565b6001600160a01b0316816001600160a01b031614611f6c5760405162461bcd60e51b815260206004820152601c60248201527f496e76616c6964206f72206f7574646174656420636f6e74726163740000000060448201526064016104f6565b6040517f6e6f64652e7265776172642e6e6574776f726b0000000000000000000000000060208201526bffffffffffffffffffffffff19606086901b166033820152611fba9060470161059d565b949350505050565b60006106548260405160200161059d91907f6e6f64652e736d6f6f7468696e672e706f6f6c2e6368616e6765642e74696d65815260609190911b6bffffffffffffffffffffffff1916602082015260340190565b600080546040517f5b49ff620000000000000000000000000000000000000000000000000000000081526001600160a01b03848116600483015261010090920490911690635b49ff62906024015b602060405180830381865afa158015612081573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106549190614ef9565b6040518060400160405280601181526020017f726f636b65744e6f64654d616e61676572000000000000000000000000000000815250306120f0826040516020016106399190614dfa565b6001600160a01b0316816001600160a01b0316146121505760405162461bcd60e51b815260206004820152601c60248201527f496e76616c6964206f72206f7574646174656420636f6e74726163740000000060448201526064016104f6565b336121a38160405160200161049391907f6e6f64652e657869737473000000000000000000000000000000000000000000815260609190911b6bffffffffffffffffffffffff1916600b820152601f0190565b6121ef5760405162461bcd60e51b815260206004820152600c60248201527f496e76616c6964206e6f6465000000000000000000000000000000000000000060448201526064016104f6565b6121f83361256f565b156122455760405162461bcd60e51b815260206004820152601360248201527f416c726561647920696e697469616c697365640000000000000000000000000060448201526064016104f6565b60006122856040518060400160405280601581526020017f726f636b65744d696e69706f6f6c4d616e61676572000000000000000000000081525061455d565b6040517f1ce9ec330000000000000000000000000000000000000000000000000000000081523360048201529091506000906001600160a01b03831690631ce9ec3390602401602060405180830381865afa1580156122e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061230c9190614e5c565b9050801561250e576000805b828110156124a7576040517f8b300029000000000000000000000000000000000000000000000000000000008152336004820152602481018290526000906001600160a01b03861690638b30002990604401602060405180830381865afa158015612387573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123ab9190614ef9565b90506002816001600160a01b0316634e69d5606040518163ffffffff1660e01b8152600401602060405180830381865afa1580156123ed573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061241191906150d5565b6004811115612422576124226150a6565b0361249657806001600160a01b031663e71501346040518163ffffffff1660e01b8152600401602060405180830381865afa158015612465573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124899190614e5c565b6124939084614ea4565b92505b506124a081614f45565b9050612318565b506040517f6e6f64652e617665726167652e6665652e6e756d657261746f7200000000000060208201526bffffffffffffffffffffffff193360601b16603a82015261250c90604e01604051602081830303815290604052805190602001208261472e565b505b612517336146a3565b5050505050565b6040517f6e6f64652e65786973747300000000000000000000000000000000000000000060208201526bffffffffffffffffffffffff19606083901b16602b82015260009061065490603f01610493565b6000806125b06040518060400160405280601c81526020017f726f636b65744e6f64654469737472696275746f72466163746f72790000000081525061455d565b6040517ffa2a5b010000000000000000000000000000000000000000000000000000000081526001600160a01b03858116600483015291925060009183169063fa2a5b0190602401602060405180830381865afa158015612615573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126399190614ef9565b3b63ffffffff161515949350505050565b6040518060400160405280601181526020017f726f636b65744e6f64654d616e6167657200000000000000000000000000000081525030612695826040516020016106399190614dfa565b6001600160a01b0316816001600160a01b0316146126f55760405162461bcd60e51b815260206004820152601c60248201527f496e76616c6964206f72206f7574646174656420636f6e74726163740000000060448201526064016104f6565b336127488160405160200161049391907f6e6f64652e657869737473000000000000000000000000000000000000000000815260609190911b6bffffffffffffffffffffffff1916600b820152601f0190565b6127945760405162461bcd60e51b815260206004820152600c60248201527f496e76616c6964206e6f6465000000000000000000000000000000000000000060448201526064016104f6565b60006127d46040518060400160405280601d81526020017f726f636b657444414f50726f746f636f6c53657474696e67734e6f646500000081525061455d565b9050806001600160a01b03166301dd16296040518163ffffffff1660e01b8152600401602060405180830381865afa158015612814573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128389190614e3f565b6128aa5760405162461bcd60e51b815260206004820152602b60248201527f536d6f6f7468696e6720706f6f6c20726567697374726174696f6e732061726560448201527f206e6f742061637469766500000000000000000000000000000000000000000060648201526084016104f6565b604080517f6e6f64652e736d6f6f7468696e672e706f6f6c2e6368616e6765642e74696d656020808301919091523360601b6bffffffffffffffffffffffff1916828401819052835160348185030181526054840185528051908301207f6e6f64652e736d6f6f7468696e672e706f6f6c2e7374617465000000000000006074850152608d8401919091528351608181850301815260a1840180865281519184019190912060e185019095529182527f726f636b657444414f50726f746f636f6c53657474696e67735265776172647360c1909301929092529091906000906129929061455d565b90506000816001600160a01b03166394e5d5126040518163ffffffff1660e01b8152600401602060405180830381865afa1580156129d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129f89190614e5c565b90506000612a0585614483565b9050612a118282614ea4565b421015612a865760405162461bcd60e51b815260206004820152602f60248201527f4e6f7420656e6f7567682074696d6520686173207061737365642073696e636560448201527f206368616e67696e67207374617465000000000000000000000000000000000060648201526084016104f6565b891515612a92856143f8565b151503612ae15760405162461bcd60e51b815260206004820152601460248201527f496e76616c6964207374617465206368616e676500000000000000000000000060448201526064016104f6565b612aeb854261472e565b612af5848b6145cc565b6040518a1515815233907fed2d3ca39683fb0f50a70ed75c33a19bfe200e529d99e6f7518453b3fc4e9be49060200160405180910390a250505050505050505050565b6040517f6e6f64652e736d6f6f7468696e672e706f6f6c2e73746174650000000000000060208201526bffffffffffffffffffffffff19606083901b16603982015260009061065490604d01610493565b6040518060400160405280601181526020017f726f636b65744e6f64654d616e6167657200000000000000000000000000000081525030612bd4826040516020016106399190614dfa565b6001600160a01b0316816001600160a01b031614612c345760405162461bcd60e51b815260206004820152601c60248201527f496e76616c6964206f72206f7574646174656420636f6e74726163740000000060448201526064016104f6565b33612c878160405160200161049391907f6e6f64652e657869737473000000000000000000000000000000000000000000815260609190911b6bffffffffffffffffffffffff1916600b820152601f0190565b612cd35760405162461bcd60e51b815260206004820152600c60248201527f496e76616c6964206e6f6465000000000000000000000000000000000000000060448201526064016104f6565b6004841015612d245760405162461bcd60e51b815260206004820181905260248201527f5468652074696d657a6f6e65206c6f636174696f6e20697320696e76616c696460448201526064016104f6565b6040517f6e6f64652e74696d657a6f6e652e6c6f636174696f6e0000000000000000000060208201526bffffffffffffffffffffffff193360601b166036820152612dbe90604a016040516020818303038152906040528051906020012086868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061465492505050565b60405142815233907fbb0b10d06b6fa081d0905e789877ce0321fafa4702ffeacaaff6e2d38063616a9060200160405180910390a25050505050565b6040517f6e6f64652e74696d657a6f6e652e6c6f636174696f6e000000000000000000006020820152606082811b6bffffffffffffffffffffffff191660368301529061065490604a016110e3565b600080612e8a6040518060400160405280601181526020017f6164647265737353657453746f7261676500000000000000000000000000000081525061455d565b90506000604051602001612ec1907f6e6f6465732e696e6465780000000000000000000000000000000000000000008152600b0190565b6040516020818303038152906040528051906020012090506000612ee36115c7565b90506000612ef18688614ea4565b905081811180612eff575085155b15612f075750805b6000875b82811015612fce576040517ff3358a3a00000000000000000000000000000000000000000000000000000000815260048101869052602481018290526000906001600160a01b0388169063f3358a3a90604401602060405180830381865afa158015612f7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f9f9190614ef9565b9050612faa81612b38565b15612fbd5782612fb981614f45565b9350505b50612fc781614f45565b9050612f0b565b50979650505050505050565b6040517f6e6f64652e72706c2e7769746864726177616c2e61646472657373000000000060208201526bffffffffffffffffffffffff19606083901b16603b820152600090819061302d90604f01610639565b90506001600160a01b038116610654576000546040517f5b49ff620000000000000000000000000000000000000000000000000000000081526001600160a01b03858116600483015261010090920490911690635b49ff62906024015b602060405180830381865afa1580156130a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105b89190614ef9565b60008061310c6040518060400160405280601181526020017f6164647265737353657453746f7261676500000000000000000000000000000081525061455d565b9050806001600160a01b031663f3358a3a604051602001613150907f6e6f6465732e696e6465780000000000000000000000000000000000000000008152600b0190565b60408051601f198184030181529082905280516020909101207fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16825260048201526024810186905260440161308a565b61328f604051806103200160405280600015158152602001600081526020016060815260200160001515815260200160006001600160a01b0316815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160006001600160a01b0316815260200160006001600160a01b031681526020016000151581526020016000815260200160006001600160a01b031681525090565b60006132cf6040518060400160405280601181526020017f726f636b65744e6f64655374616b696e6700000000000000000000000000000081525061455d565b905060006133116040518060400160405280601181526020017f726f636b65744e6f64654465706f73697400000000000000000000000000000081525061455d565b905060006133536040518060400160405280601c81526020017f726f636b65744e6f64654469737472696275746f72466163746f72790000000081525061455d565b905060006133956040518060400160405280601581526020017f726f636b65744d696e69706f6f6c4d616e61676572000000000000000000000081525061455d565b905060006133d76040518060400160405280600f81526020017f726f636b6574546f6b656e52455448000000000000000000000000000000000081525061455d565b905060006134196040518060400160405280600e81526020017f726f636b6574546f6b656e52504c00000000000000000000000000000000000081525061455d565b9050600061345b6040518060400160405280601981526020017f726f636b6574546f6b656e52504c4669786564537570706c790000000000000081525061455d565b6001600160a01b038a81166103008b018190526000546040517f5b49ff6200000000000000000000000000000000000000000000000000000000815260048101929092529293506101009092041690635b49ff6290602401602060405180830381865afa1580156134d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134f49190614ef9565b6001600160a01b039081166102808a01526000546040517ffd4125130000000000000000000000000000000000000000000000000000000081528b831660048201526101009091049091169063fd41251390602401602060405180830381865afa158015613566573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061358a9190614ef9565b6001600160a01b03166102a08901526135a28961251e565b151588526135af89610444565b60208901526135bd89612dfa565b60408901526135cb8961256f565b151560608901526135db89611ebf565b60a08901526040517f9961cee40000000000000000000000000000000000000000000000000000000081526001600160a01b038a81166004830152881690639961cee490602401602060405180830381865afa15801561363f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136639190614e5c565b60c08901526040517ff0d19b890000000000000000000000000000000000000000000000000000000081526001600160a01b038a8116600483015288169063f0d19b8990602401602060405180830381865afa1580156136c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136eb9190614e5c565b60e08901526040517f03fa87b40000000000000000000000000000000000000000000000000000000081526001600160a01b038a811660048301528816906303fa87b490602401602060405180830381865afa15801561374f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137739190614e5c565b6101008901526040517f4e58ff6e0000000000000000000000000000000000000000000000000000000081526001600160a01b038a81166004830152881690634e58ff6e90602401602060405180830381865afa1580156137d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137fc9190614e5c565b6101208901526040517fa493e6a20000000000000000000000000000000000000000000000000000000081526001600160a01b038a8116600483015288169063a493e6a290602401602060405180830381865afa158015613861573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138859190614e5c565b6101408901526040517f48aeedf50000000000000000000000000000000000000000000000000000000081526001600160a01b038a811660048301528816906348aeedf590602401602060405180830381865afa1580156138ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061390e9190614e5c565b6101608901526040517ffa2a5b010000000000000000000000000000000000000000000000000000000081526001600160a01b038a8116600483015286169063fa2a5b0190602401602060405180830381865afa158015613973573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139979190614ef9565b6001600160a01b031660808901819052604080517f372d054b000000000000000000000000000000000000000000000000000000008152905182319291829163372d054b916004808201926020929091908290030181865afa158015613a01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a259190614e5c565b6102608b01819052613a379083614eb7565b6102408b01526040517f1ce9ec330000000000000000000000000000000000000000000000000000000081526001600160a01b038c81166004830152871690631ce9ec3390602401602060405180830381865afa158015613a9c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ac09190614e5c565b6101808b01526001600160a01b038b811680316101a08d01526040517f70a082310000000000000000000000000000000000000000000000000000000081526004810191909152908616906370a0823190602401602060405180830381865afa158015613b31573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b559190614e5c565b6101c08b01526040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b038c811660048301528516906370a0823190602401602060405180830381865afa158015613bba573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bde9190614e5c565b6101e08b01526040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b038c811660048301528416906370a0823190602401602060405180830381865afa158015613c43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c679190614e5c565b6102008b01526040517f493c94670000000000000000000000000000000000000000000000000000000081526001600160a01b038c8116600483015289169063493c946790602401602060405180830381865afa158015613ccc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613cf09190614e5c565b6102208b015250979998505050505050505050565b6040518060400160405280601181526020017f726f636b65744e6f64654d616e6167657200000000000000000000000000000081525030613d50826040516020016106399190614dfa565b6001600160a01b0316816001600160a01b031614613db05760405162461bcd60e51b815260206004820152601c60248201527f496e76616c6964206f72206f7574646174656420636f6e74726163740000000060448201526064016104f6565b600080546040517f5b49ff620000000000000000000000000000000000000000000000000000000081526001600160a01b03878116600483015261010090920490911690635b49ff6290602401602060405180830381865afa158015613e1a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e3e9190614ef9565b90506001600160a01b0381163314613ee55760405162461bcd60e51b8152602060048201526044602482018190527f4f6e6c7920612074782066726f6d2061206e6f64652773207769746864726177908201527f616c20616464726573732063616e206368616e676520726577617264206e657460648201527f776f726b00000000000000000000000000000000000000000000000000000000608482015260a4016104f6565b6000613f086040518060600160405280602381526020016151c56023913961455d565b6040517f6dd2623e000000000000000000000000000000000000000000000000000000008152600481018790529091506001600160a01b03821690636dd2623e90602401602060405180830381865afa158015613f69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f8d9190614e3f565b613fd95760405162461bcd60e51b815260206004820152601660248201527f4e6574776f726b206973206e6f7420656e61626c65640000000000000000000060448201526064016104f6565b6040517f6e6f64652e7265776172642e6e6574776f726b0000000000000000000000000060208201526bffffffffffffffffffffffff19606088901b16603382015261403e90604701604051602081830303815290604052805190602001208661472e565b856001600160a01b03167f7c50987deec06761094239e9ff28caa9cfdd305f9c65011c284a0e40cbf4cfdc8660405161407991815260200190565b60405180910390a2505050505050565b6040517f6e6f64652e72706c2e7769746864726177616c2e61646472657373000000000060208201526bffffffffffffffffffffffff19606083901b16603b82015260009081906140dc90604f01610639565b6001600160a01b0316141592915050565b6040517f6e6f64652e65786973747300000000000000000000000000000000000000000060208201526bffffffffffffffffffffffff19606085901b16602b820152839061413d90603f01610493565b6141895760405162461bcd60e51b815260206004820152600c60248201527f496e76616c6964206e6f6465000000000000000000000000000000000000000060448201526064016104f6565b6001600160a01b0383166141df5760405162461bcd60e51b815260206004820152601e60248201527f496e76616c69642052504c207769746864726177616c2061646472657373000060448201526064016104f6565b60006141ea85612fda565b90506001600160a01b038116331461426a5760405162461bcd60e51b815260206004820152603c60248201527f4f6e6c7920612074782066726f6d2061206e6f646527732052504c207769746860448201527f64726177616c20616464726573732063616e207570646174652069740000000060648201526084016104f6565b821561431257614303856040516020016142e891907f6e6f64652e70656e64696e672e72706c2e7769746864726177616c2e6164647281527f6573730000000000000000000000000000000000000000000000000000000000602082015260609190911b6bffffffffffffffffffffffff1916602382015260370190565b60405160208183030381529060405280519060200120614813565b61430d858561488a565b612517565b6125178560405160200161438a91907f6e6f64652e70656e64696e672e72706c2e7769746864726177616c2e6164647281527f6573730000000000000000000000000000000000000000000000000000000000602082015260609190911b6bffffffffffffffffffffffff1916602382015260370190565b6040516020818303038152906040528051906020012085614940565b600080546040517ffd4125130000000000000000000000000000000000000000000000000000000081526001600160a01b0384811660048301526101009092049091169063fd41251390602401612064565b600080546040517f7ae1cfca000000000000000000000000000000000000000000000000000000008152600481018490526101009091046001600160a01b031690637ae1cfca90602401602060405180830381865afa15801561445f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106549190614e3f565b600080546040517fbd02d0f5000000000000000000000000000000000000000000000000000000008152600481018490526101009091046001600160a01b03169063bd02d0f590602401602060405180830381865afa1580156144ea573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106549190614e5c565b600080546040517f21f8a721000000000000000000000000000000000000000000000000000000008152600481018490526101009091046001600160a01b0316906321f8a72190602401612064565b600080614574836040516020016106399190614dfa565b90506001600160a01b0381166106545760405162461bcd60e51b815260206004820152601260248201527f436f6e7472616374206e6f7420666f756e64000000000000000000000000000060448201526064016104f6565b6000546040517fabfdcced0000000000000000000000000000000000000000000000000000000081526004810184905282151560248201526101009091046001600160a01b03169063abfdcced906044015b600060405180830381600087803b15801561463857600080fd5b505af115801561464c573d6000803e3d6000fd5b505050505050565b6000546040517f6e8995500000000000000000000000000000000000000000000000000000000081526101009091046001600160a01b031690636e8995509061461e90859085906004016150f6565b60006146e36040518060400160405280601c81526020017f726f636b65744e6f64654469737472696275746f72466163746f72790000000081525061455d565b6040517f6140c54c0000000000000000000000000000000000000000000000000000000081526001600160a01b03848116600483015291925090821690636140c54c9060240161461e565b6000546040517fe2a4853a00000000000000000000000000000000000000000000000000000000815260048101849052602481018390526101009091046001600160a01b03169063e2a4853a9060440161461e565b6000546040517f986e791a0000000000000000000000000000000000000000000000000000000081526004810183905260609161010090046001600160a01b03169063986e791a90602401600060405180830381865afa1580156147eb573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610654919081019061510f565b6000546040517f0e14a376000000000000000000000000000000000000000000000000000000008152600481018390526101009091046001600160a01b031690630e14a37690602401600060405180830381600087803b15801561487657600080fd5b505af1158015612517573d6000803e3d6000fd5b6040517f6e6f64652e72706c2e7769746864726177616c2e61646472657373000000000060208201526bffffffffffffffffffffffff19606084901b16603b8201526148ef90604f016040516020818303038152906040528051906020012082614940565b806001600160a01b0316826001600160a01b03167f18702dcdad68e2a2d4350dc9f33402b58fd397352dd47a45312fccd5ff1e52a64260405161493491815260200190565b60405180910390a35050565b6000546040517fca446dd9000000000000000000000000000000000000000000000000000000008152600481018490526001600160a01b0383811660248301526101009092049091169063ca446dd99060440161461e565b6001600160a01b03811681146149ad57600080fd5b50565b6000602082840312156149c257600080fd5b81356105b881614998565b600080602083850312156149e057600080fd5b823567ffffffffffffffff808211156149f857600080fd5b818501915085601f830112614a0c57600080fd5b813581811115614a1b57600080fd5b866020828501011115614a2d57600080fd5b60209290920196919550909350505050565b60008060408385031215614a5257600080fd5b50508035926020909101359150565b60005b83811015614a7c578181015183820152602001614a64565b50506000910152565b60008151808452614a9d816020860160208601614a61565b601f01601f19169290920160200192915050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b83811015614b37577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc089840301855281518051878552614b1a88860182614a85565b918901519489019490945294870194925090860190600101614ad8565b509098975050505050505050565b6020808252825182820181905260009190848201906040850190845b81811015614b865783516001600160a01b031683529284019291840191600101614b61565b50909695505050505050565b80151581146149ad57600080fd5b600060208284031215614bb257600080fd5b81356105b881614b92565b6020815260006105b86020830184614a85565b600060208284031215614be257600080fd5b5035919050565b60208152614bfc60208201835115159052565b6020820151604082015260006040830151610320806060850152614c24610340850183614a85565b91506060850151614c39608086018215159052565b5060808501516001600160a01b03811660a08601525060a085015160c08581019190915285015160e08086019190915285015161010080860191909152850151610120808601919091528501516101408086019190915285015161016080860191909152850151610180808601919091528501516101a0808601919091528501516101c0808601919091528501516101e08086019190915285015161020080860191909152850151610220808601919091528501516102408086019190915285015161026080860191909152850151610280808601919091528501516102a0614d2c818701836001600160a01b03169052565b86015190506102c0614d48868201836001600160a01b03169052565b86015190506102e0614d5d8682018315159052565b86015161030086810191909152909501516001600160a01b031693019290925250919050565b60008060408385031215614d9657600080fd5b8235614da181614998565b946020939093013593505050565b600080600060608486031215614dc457600080fd5b8335614dcf81614998565b92506020840135614ddf81614998565b91506040840135614def81614b92565b809150509250925092565b7f636f6e74726163742e6164647265737300000000000000000000000000000000815260008251614e32816010850160208701614a61565b9190910160100192915050565b600060208284031215614e5157600080fd5b81516105b881614b92565b600060208284031215614e6e57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561065457610654614e75565b8181038181111561065457610654614e75565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060208284031215614f0b57600080fd5b81516105b881614998565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614f7657614f76614e75565b5060010190565b604051601f8201601f1916810167ffffffffffffffff81118282101715614fa657614fa6614eca565b604052919050565b60006020808385031215614fc157600080fd5b825167ffffffffffffffff80821115614fd957600080fd5b818501915085601f830112614fed57600080fd5b815181811115614fff57614fff614eca565b8060051b9150615010848301614f7d565b818152918301840191848101908884111561502a57600080fd5b938501935b838510156150485784518252938501939085019061502f565b98975050505050505050565b808202811582820484141761065457610654614e75565b6000826150a1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000602082840312156150e757600080fd5b8151600581106105b857600080fd5b828152604060208201526000611fba6040830184614a85565b60006020828403121561512157600080fd5b815167ffffffffffffffff8082111561513957600080fd5b818401915084601f83011261514d57600080fd5b81518181111561515f5761515f614eca565b6151726020601f19601f84011601614f7d565b915080825285602082850101111561518957600080fd5b61519a816020840160208601614a61565b5094935050505056fe726f636b657444414f50726f746f636f6c53657474696e67734d696e69706f6f6c726f636b657444414f4e6f64655472757374656453657474696e677352657761726473a26469706673582212208ef43a11b82f36494be1b70455eb2dcafd96867e73f138cfd1c8173ae35cacc264736f6c63430008120033000000000000000000000000594fb75d3dc2dfa0150ad03f99f97817747dd4e1
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101c45760003560e01c806365d4176f116100f9578063b71f0c7c11610097578063d565f27611610071578063d565f276146103f8578063e667d8281461040b578063f5b17b421461041e578063fd4125131461043157600080fd5b8063b71f0c7c146103b2578063ba75d806146103c5578063bafb3581146103d857600080fd5b8063a4cef9dd116100d3578063a4cef9dd14610359578063a7e6e8b31461036c578063b018f0261461037f578063b715a1aa1461039f57600080fd5b806365d4176f14610310578063927ece4f1461033357806399283f8b1461034657600080fd5b80633a643648116101665780634d99f633116101405780634d99f633146102c357806354fd4d50146102d65780635b49ff62146102f557806364908a861461030857600080fd5b80633a6436481461028a578063414dd1d21461029d57806343f88981146102b057600080fd5b806329554540116101a2578063295545401461022f5780632a7968eb1461024f5780632d7f21d01461026257806339bf397e1461028257600080fd5b806302d8a732146101c95780631ac3c0a8146101ef57806327c6f43e1461021a575b600080fd5b6101dc6101d73660046149b0565b610444565b6040519081526020015b60405180910390f35b6102026101fd3660046149b0565b6105bf565b6040516001600160a01b0390911681526020016101e6565b61022d6102283660046149cd565b61065a565b005b61024261023d366004614a3f565b610e54565b6040516101e69190614ab1565b61022d61025d3660046149b0565b6111ff565b610275610270366004614a3f565b6113db565b6040516101e69190614b45565b6101dc6115c7565b61022d6102983660046149b0565b6116c7565b6101dc6102ab3660046149b0565b611899565b6101dc6102be3660046149b0565b611ebf565b6101dc6102d13660046149b0565b611fc2565b6000546102e39060ff1681565b60405160ff90911681526020016101e6565b6102026103033660046149b0565b612016565b61022d6120a5565b61032361031e3660046149b0565b61251e565b60405190151581526020016101e6565b6103236103413660046149b0565b61256f565b61022d610354366004614ba0565b61264a565b6103236103673660046149b0565b612b38565b61022d61037a3660046149cd565b612b89565b61039261038d3660046149b0565b612dfa565b6040516101e69190614bbd565b6101dc6103ad366004614a3f565b612e49565b6102026103c03660046149b0565b612fda565b6102026103d3366004614bd0565b6130cb565b6103eb6103e63660046149b0565b6131a6565b6040516101e69190614be9565b61022d610406366004614d83565b613d05565b6103236104193660046149b0565b614089565b61022d61042c366004614daf565b6140ed565b61020261043f3660046149b0565b6143a6565b6040517f6e6f64652e65786973747300000000000000000000000000000000000000000060208201526bffffffffffffffffffffffff19606083901b16602b82015260009082906104ae90603f015b604051602081830303815290604052805190602001206143f8565b6104ff5760405162461bcd60e51b815260206004820152600c60248201527f496e76616c6964206e6f6465000000000000000000000000000000000000000060448201526064015b60405180910390fd5b6105b88360405160200161059d91907f726577617264732e706f6f6c2e636c61696d2e636f6e74726163742e7265676981527f7374657265642e74696d6500000000000000000000000000000000000000000060208201527f726f636b6574436c61696d4e6f64650000000000000000000000000000000000602b82015260609190911b6bffffffffffffffffffffffff1916603a820152604e0190565b60405160208183030381529060405280519060200120614483565b9392505050565b60006106548260405160200161063991907f6e6f64652e70656e64696e672e72706c2e7769746864726177616c2e6164647281527f6573730000000000000000000000000000000000000000000000000000000000602082015260609190911b6bffffffffffffffffffffffff1916602382015260370190565b6040516020818303038152906040528051906020012061450e565b92915050565b6040518060400160405280601181526020017f726f636b65744e6f64654d616e61676572000000000000000000000000000000815250306106a5826040516020016106399190614dfa565b6001600160a01b0316816001600160a01b0316146107055760405162461bcd60e51b815260206004820152601c60248201527f496e76616c6964206f72206f7574646174656420636f6e74726163740000000060448201526064016104f6565b60006107456040518060400160405280601d81526020017f726f636b657444414f50726f746f636f6c53657474696e67734e6f646500000081525061455d565b905060006107876040518060400160405280601181526020017f6164647265737353657453746f7261676500000000000000000000000000000081525061455d565b905060006107c96040518060400160405280601681526020017f726f636b65744e6574776f726b536e617073686f74730000000000000000000081525061455d565b9050826001600160a01b03166387b1bb116040518163ffffffff1660e01b8152600401602060405180830381865afa158015610809573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061082d9190614e3f565b61089f5760405162461bcd60e51b815260206004820152603560248201527f526f636b657420506f6f6c206e6f646520726567697374726174696f6e73206160448201527f72652063757272656e746c792064697361626c6564000000000000000000000060648201526084016104f6565b60048610156108f05760405162461bcd60e51b815260206004820181905260248201527f5468652074696d657a6f6e65206c6f636174696f6e20697320696e76616c696460448201526064016104f6565b6040517f6e6f64652e65786973747300000000000000000000000000000000000000000060208201526bffffffffffffffffffffffff193360601b16602b82015261095690603f015b6040516020818303038152906040528051906020012060016145cc565b6040517f6e6f64652e766f74696e672e656e61626c65640000000000000000000000000060208201526bffffffffffffffffffffffff193360601b1660338201526109a390604701610939565b6040517f6e6f64652e74696d657a6f6e652e6c6f636174696f6e0000000000000000000060208201526bffffffffffffffffffffffff193360601b166036820152610a3d90604a016040516020818303038152906040528051906020012088888080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061465492505050565b6040517f6e6f6465732e696e6465780000000000000000000000000000000000000000006020820152600090602b0160408051808303601f190181529082905280516020909101207f889271660000000000000000000000000000000000000000000000000000000082526004820181905233602483015291506001600160a01b03841690638892716690604401600060405180830381600087803b158015610ae557600080fd5b505af1158015610af9573d6000803e3d6000fd5b50505050610b06336146a3565b604080517f726577617264732e706f6f6c2e636c61696d2e636f6e74726163742e7265676960208201527f7374657265642e74696d65000000000000000000000000000000000000000000918101919091527f726f636b6574436c61696d4e6f64650000000000000000000000000000000000604b8201526bffffffffffffffffffffffff193360601b16605a820152610bb990606e01604051602081830303815290604052805190602001204261472e565b816001600160a01b0316635ba59649604051602001610bfb907f6e6f64652e636f756e74000000000000000000000000000000000000000000008152600a0190565b60408051601f198184030181529082905280516020909101207fc9d6fee900000000000000000000000000000000000000000000000000000000825260048201859052906001600160a01b0387169063c9d6fee990602401602060405180830381865afa158015610c70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c949190614e5c565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b16815260048101929092527bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166024820152604401600060405180830381600087803b158015610d0857600080fd5b505af1158015610d1c573d6000803e3d6000fd5b50506040517f6e6f64652e64656c65676174650000000000000000000000000000000000000060208201526bffffffffffffffffffffffff193360601b16602d8201526001600160a01b0385169250635ba59649915060410160408051808303601f1901815290829052805160209091012060e083901b7fffffffff0000000000000000000000000000000000000000000000000000000016825260048201527bffffffffffffffffffffffffffffffffffffffffffffffffffffffff33166024820152604401600060405180830381600087803b158015610dfd57600080fd5b505af1158015610e11573d6000803e3d6000fd5b50506040514281523392507ff773bca07d020a1bc1fdd45ea3db573da547dd27180143afaf075c158a847594915060200160405180910390a25050505050505050565b60606000610e966040518060400160405280601181526020017f6164647265737353657453746f7261676500000000000000000000000000000081525061455d565b90506000604051602001610ecd907f6e6f6465732e696e6465780000000000000000000000000000000000000000008152600b0190565b60408051601f198184030181529082905280516020909101207fc9d6fee90000000000000000000000000000000000000000000000000000000082526004820181905291506000906001600160a01b0384169063c9d6fee990602401602060405180830381865afa158015610f46573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6a9190614e5c565b90506000610f788688614ea4565b905081811180610f86575085155b15610f8e5750805b6000610f9a8883614eb7565b67ffffffffffffffff811115610fb257610fb2614eca565b604051908082528060200260200182016040528015610ff857816020015b604080518082019091526060815260006020820152815260200190600190039081610fd05790505b5090506000885b838110156111f1576040517ff3358a3a00000000000000000000000000000000000000000000000000000000815260048101879052602481018290526000906001600160a01b0389169063f3358a3a90604401602060405180830381865afa15801561106f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110939190614ef9565b6040517f6e6f64652e74696d657a6f6e652e6c6f636174696f6e0000000000000000000060208201526bffffffffffffffffffffffff19606083901b1660368201529091506000906110fe90604a015b60405160208183030381529060405280519060200120614783565b90506000805b8581101561118557828051906020012087828151811061112657611126614f16565b6020026020010151600001518051906020012003611175576001915086818151811061115457611154614f16565b6020026020010151602001805180919061116d90614f45565b905250611185565b61117e81614f45565b9050611104565b50806111dd578186868151811061119e5761119e614f16565b60200260200101516000018190525060018686815181106111c1576111c1614f16565b6020908102919091018101510152846111d981614f45565b9550505b505050806111ea90614f45565b9050610fff565b508152979650505050505050565b6040517f6e6f64652e65786973747300000000000000000000000000000000000000000060208201526bffffffffffffffffffffffff19606083901b16602b820152819061124f90603f01610493565b61129b5760405162461bcd60e51b815260206004820152600c60248201527f496e76616c6964206e6f6465000000000000000000000000000000000000000060448201526064016104f6565b6040517f6e6f64652e72706c2e7769746864726177616c2e61646472657373000000000060208201526bffffffffffffffffffffffff19606084901b16603b820152600090604f01604051602081830303815290604052805190602001209050336001600160a01b031661130e8261450e565b6001600160a01b03161461138a5760405162461bcd60e51b815260206004820152603b60248201527f4f6e6c7920612074782066726f6d2061206e6f646527732052504c207769746860448201527f64726177616c20616464726573732063616e20756e736574206974000000000060648201526084016104f6565b61139381614813565b826001600160a01b03167fb62e03dab231209df2b46d49d4aa960deab93ff886a706653b5fc6b7ab57073f426040516113ce91815260200190565b60405180910390a2505050565b6060600061141d6040518060400160405280601181526020017f6164647265737353657453746f7261676500000000000000000000000000000081525061455d565b90506000604051602001611454907f6e6f6465732e696e6465780000000000000000000000000000000000000000008152600b0190565b60405160208183030381529060405280519060200120905060006114766115c7565b905060006114848688614ea4565b905081811180611492575085155b1561149a5750805b60006114a68883614eb7565b67ffffffffffffffff8111156114be576114be614eca565b6040519080825280602002602001820160405280156114e7578160200160208202803683370190505b5090506000885b838110156111f1576040517ff3358a3a00000000000000000000000000000000000000000000000000000000815260048101879052602481018290526001600160a01b0388169063f3358a3a90604401602060405180830381865afa15801561155b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061157f9190614ef9565b83838151811061159157611591614f16565b6001600160a01b0390921660209283029190910190910152816115b381614f45565b925050806115c090614f45565b90506114ee565b6000806116086040518060400160405280601181526020017f6164647265737353657453746f7261676500000000000000000000000000000081525061455d565b9050806001600160a01b031663c9d6fee960405160200161164c907f6e6f6465732e696e6465780000000000000000000000000000000000000000008152600b0190565b604051602081830303815290604052805190602001206040518263ffffffff1660e01b815260040161168091815260200190565b602060405180830381865afa15801561169d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116c19190614e5c565b91505090565b6040517f6e6f64652e65786973747300000000000000000000000000000000000000000060208201526bffffffffffffffffffffffff19606083901b16602b820152819061171790603f01610493565b6117635760405162461bcd60e51b815260206004820152600c60248201527f496e76616c6964206e6f6465000000000000000000000000000000000000000060448201526064016104f6565b6000826040516020016117da91907f6e6f64652e70656e64696e672e72706c2e7769746864726177616c2e6164647281527f6573730000000000000000000000000000000000000000000000000000000000602082015260609190911b6bffffffffffffffffffffffff1916602382015260370190565b604051602081830303815290604052805190602001209050336001600160a01b03166118058261450e565b6001600160a01b0316146118815760405162461bcd60e51b815260206004820152603e60248201527f436f6e6669726d6174696f6e206d75737420636f6d652066726f6d207468652060448201527f70656e64696e672052504c207769746864726177616c2061646472657373000060648201526084016104f6565b61188a81614813565b611894833361488a565b505050565b6000806118da6040518060400160405280601581526020017f726f636b65744d696e69706f6f6c4d616e61676572000000000000000000000081525061455d565b9050600061191c6040518060400160405280601181526020017f726f636b65744e6f64654465706f73697400000000000000000000000000000081525061455d565b905060006119416040518060600160405280602181526020016151a46021913961455d565b90506000826001600160a01b0316639bed5a456040518163ffffffff1660e01b8152600401600060405180830381865afa158015611983573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526119ab9190810190614fae565b90506000815167ffffffffffffffff8111156119c9576119c9614eca565b6040519080825280602002602001820160405280156119f2578160200160208202803683370190505b5090506000825167ffffffffffffffff811115611a1157611a11614eca565b604051908082528060200260200182016040528015611a3a578160200160208202803683370190505b5090506000806000866001600160a01b03166308e50d386040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aa49190614e5c565b905060005b8651811015611ba357896001600160a01b031663240eb3308d898481518110611ad457611ad4614f16565b60200260200101516040518363ffffffff1660e01b8152600401611b0d9291906001600160a01b03929092168252602082015260400190565b602060405180830381865afa158015611b2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b4e9190614e5c565b858281518110611b6057611b60614f16565b602002602001018181525050848181518110611b7e57611b7e614f16565b602002602001015183611b919190614ea4565b9250611b9c81614f45565b9050611aa9565b5081600003611bbd575060009a9950505050505050505050565b60005b8651811015611c6757848181518110611bdb57611bdb614f16565b6020026020010151878281518110611bf557611bf5614f16565b602002602001015183611c089190614eb7565b611c129190615054565b868281518110611c2457611c24614f16565b602002602001018181525050858181518110611c4257611c42614f16565b602002602001015184611c559190614ea4565b9350611c6081614f45565b9050611bc0565b5060005b8651811015611cd95783670de0b6b3a7640000878381518110611c9057611c90614f16565b6020026020010151611ca29190615054565b611cac919061506b565b868281518110611cbe57611cbe614f16565b6020908102919091010152611cd281614f45565b9050611c6b565b506000805b8751811015611e9c576000868281518110611cfb57611cfb614f16565b60200260200101511115611e8c576000888281518110611d1d57611d1d614f16565b602002602001015167de0b6b3a7640000003611d9f578d604051602001611d8291907f6e6f64652e617665726167652e6665652e6e756d657261746f72000000000000815260609190911b6bffffffffffffffffffffffff1916601a820152602e0190565b604051602081830303815290604052805190602001209050611e27565b8d898381518110611db257611db2614f16565b6020026020010151604051602001611e0e9291907f6e6f64652e617665726167652e6665652e6e756d657261746f72000000000000815260609290921b6bffffffffffffffffffffffff1916601a830152602e820152604e0190565b6040516020818303038152906040528051906020012090505b6000611e3282614483565b9050878381518110611e4657611e46614f16565b6020026020010151898481518110611e6057611e60614f16565b602002602001015182611e739190615054565b611e7d919061506b565b611e879085614ea4565b935050505b611e9581614f45565b9050611cde565b50611eaf670de0b6b3a76400008261506b565b9c9b505050505050505050505050565b60006040518060400160405280601181526020017f726f636b65744e6f64654d616e6167657200000000000000000000000000000081525030611f0c826040516020016106399190614dfa565b6001600160a01b0316816001600160a01b031614611f6c5760405162461bcd60e51b815260206004820152601c60248201527f496e76616c6964206f72206f7574646174656420636f6e74726163740000000060448201526064016104f6565b6040517f6e6f64652e7265776172642e6e6574776f726b0000000000000000000000000060208201526bffffffffffffffffffffffff19606086901b166033820152611fba9060470161059d565b949350505050565b60006106548260405160200161059d91907f6e6f64652e736d6f6f7468696e672e706f6f6c2e6368616e6765642e74696d65815260609190911b6bffffffffffffffffffffffff1916602082015260340190565b600080546040517f5b49ff620000000000000000000000000000000000000000000000000000000081526001600160a01b03848116600483015261010090920490911690635b49ff62906024015b602060405180830381865afa158015612081573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106549190614ef9565b6040518060400160405280601181526020017f726f636b65744e6f64654d616e61676572000000000000000000000000000000815250306120f0826040516020016106399190614dfa565b6001600160a01b0316816001600160a01b0316146121505760405162461bcd60e51b815260206004820152601c60248201527f496e76616c6964206f72206f7574646174656420636f6e74726163740000000060448201526064016104f6565b336121a38160405160200161049391907f6e6f64652e657869737473000000000000000000000000000000000000000000815260609190911b6bffffffffffffffffffffffff1916600b820152601f0190565b6121ef5760405162461bcd60e51b815260206004820152600c60248201527f496e76616c6964206e6f6465000000000000000000000000000000000000000060448201526064016104f6565b6121f83361256f565b156122455760405162461bcd60e51b815260206004820152601360248201527f416c726561647920696e697469616c697365640000000000000000000000000060448201526064016104f6565b60006122856040518060400160405280601581526020017f726f636b65744d696e69706f6f6c4d616e61676572000000000000000000000081525061455d565b6040517f1ce9ec330000000000000000000000000000000000000000000000000000000081523360048201529091506000906001600160a01b03831690631ce9ec3390602401602060405180830381865afa1580156122e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061230c9190614e5c565b9050801561250e576000805b828110156124a7576040517f8b300029000000000000000000000000000000000000000000000000000000008152336004820152602481018290526000906001600160a01b03861690638b30002990604401602060405180830381865afa158015612387573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123ab9190614ef9565b90506002816001600160a01b0316634e69d5606040518163ffffffff1660e01b8152600401602060405180830381865afa1580156123ed573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061241191906150d5565b6004811115612422576124226150a6565b0361249657806001600160a01b031663e71501346040518163ffffffff1660e01b8152600401602060405180830381865afa158015612465573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124899190614e5c565b6124939084614ea4565b92505b506124a081614f45565b9050612318565b506040517f6e6f64652e617665726167652e6665652e6e756d657261746f7200000000000060208201526bffffffffffffffffffffffff193360601b16603a82015261250c90604e01604051602081830303815290604052805190602001208261472e565b505b612517336146a3565b5050505050565b6040517f6e6f64652e65786973747300000000000000000000000000000000000000000060208201526bffffffffffffffffffffffff19606083901b16602b82015260009061065490603f01610493565b6000806125b06040518060400160405280601c81526020017f726f636b65744e6f64654469737472696275746f72466163746f72790000000081525061455d565b6040517ffa2a5b010000000000000000000000000000000000000000000000000000000081526001600160a01b03858116600483015291925060009183169063fa2a5b0190602401602060405180830381865afa158015612615573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126399190614ef9565b3b63ffffffff161515949350505050565b6040518060400160405280601181526020017f726f636b65744e6f64654d616e6167657200000000000000000000000000000081525030612695826040516020016106399190614dfa565b6001600160a01b0316816001600160a01b0316146126f55760405162461bcd60e51b815260206004820152601c60248201527f496e76616c6964206f72206f7574646174656420636f6e74726163740000000060448201526064016104f6565b336127488160405160200161049391907f6e6f64652e657869737473000000000000000000000000000000000000000000815260609190911b6bffffffffffffffffffffffff1916600b820152601f0190565b6127945760405162461bcd60e51b815260206004820152600c60248201527f496e76616c6964206e6f6465000000000000000000000000000000000000000060448201526064016104f6565b60006127d46040518060400160405280601d81526020017f726f636b657444414f50726f746f636f6c53657474696e67734e6f646500000081525061455d565b9050806001600160a01b03166301dd16296040518163ffffffff1660e01b8152600401602060405180830381865afa158015612814573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128389190614e3f565b6128aa5760405162461bcd60e51b815260206004820152602b60248201527f536d6f6f7468696e6720706f6f6c20726567697374726174696f6e732061726560448201527f206e6f742061637469766500000000000000000000000000000000000000000060648201526084016104f6565b604080517f6e6f64652e736d6f6f7468696e672e706f6f6c2e6368616e6765642e74696d656020808301919091523360601b6bffffffffffffffffffffffff1916828401819052835160348185030181526054840185528051908301207f6e6f64652e736d6f6f7468696e672e706f6f6c2e7374617465000000000000006074850152608d8401919091528351608181850301815260a1840180865281519184019190912060e185019095529182527f726f636b657444414f50726f746f636f6c53657474696e67735265776172647360c1909301929092529091906000906129929061455d565b90506000816001600160a01b03166394e5d5126040518163ffffffff1660e01b8152600401602060405180830381865afa1580156129d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129f89190614e5c565b90506000612a0585614483565b9050612a118282614ea4565b421015612a865760405162461bcd60e51b815260206004820152602f60248201527f4e6f7420656e6f7567682074696d6520686173207061737365642073696e636560448201527f206368616e67696e67207374617465000000000000000000000000000000000060648201526084016104f6565b891515612a92856143f8565b151503612ae15760405162461bcd60e51b815260206004820152601460248201527f496e76616c6964207374617465206368616e676500000000000000000000000060448201526064016104f6565b612aeb854261472e565b612af5848b6145cc565b6040518a1515815233907fed2d3ca39683fb0f50a70ed75c33a19bfe200e529d99e6f7518453b3fc4e9be49060200160405180910390a250505050505050505050565b6040517f6e6f64652e736d6f6f7468696e672e706f6f6c2e73746174650000000000000060208201526bffffffffffffffffffffffff19606083901b16603982015260009061065490604d01610493565b6040518060400160405280601181526020017f726f636b65744e6f64654d616e6167657200000000000000000000000000000081525030612bd4826040516020016106399190614dfa565b6001600160a01b0316816001600160a01b031614612c345760405162461bcd60e51b815260206004820152601c60248201527f496e76616c6964206f72206f7574646174656420636f6e74726163740000000060448201526064016104f6565b33612c878160405160200161049391907f6e6f64652e657869737473000000000000000000000000000000000000000000815260609190911b6bffffffffffffffffffffffff1916600b820152601f0190565b612cd35760405162461bcd60e51b815260206004820152600c60248201527f496e76616c6964206e6f6465000000000000000000000000000000000000000060448201526064016104f6565b6004841015612d245760405162461bcd60e51b815260206004820181905260248201527f5468652074696d657a6f6e65206c6f636174696f6e20697320696e76616c696460448201526064016104f6565b6040517f6e6f64652e74696d657a6f6e652e6c6f636174696f6e0000000000000000000060208201526bffffffffffffffffffffffff193360601b166036820152612dbe90604a016040516020818303038152906040528051906020012086868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061465492505050565b60405142815233907fbb0b10d06b6fa081d0905e789877ce0321fafa4702ffeacaaff6e2d38063616a9060200160405180910390a25050505050565b6040517f6e6f64652e74696d657a6f6e652e6c6f636174696f6e000000000000000000006020820152606082811b6bffffffffffffffffffffffff191660368301529061065490604a016110e3565b600080612e8a6040518060400160405280601181526020017f6164647265737353657453746f7261676500000000000000000000000000000081525061455d565b90506000604051602001612ec1907f6e6f6465732e696e6465780000000000000000000000000000000000000000008152600b0190565b6040516020818303038152906040528051906020012090506000612ee36115c7565b90506000612ef18688614ea4565b905081811180612eff575085155b15612f075750805b6000875b82811015612fce576040517ff3358a3a00000000000000000000000000000000000000000000000000000000815260048101869052602481018290526000906001600160a01b0388169063f3358a3a90604401602060405180830381865afa158015612f7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f9f9190614ef9565b9050612faa81612b38565b15612fbd5782612fb981614f45565b9350505b50612fc781614f45565b9050612f0b565b50979650505050505050565b6040517f6e6f64652e72706c2e7769746864726177616c2e61646472657373000000000060208201526bffffffffffffffffffffffff19606083901b16603b820152600090819061302d90604f01610639565b90506001600160a01b038116610654576000546040517f5b49ff620000000000000000000000000000000000000000000000000000000081526001600160a01b03858116600483015261010090920490911690635b49ff62906024015b602060405180830381865afa1580156130a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105b89190614ef9565b60008061310c6040518060400160405280601181526020017f6164647265737353657453746f7261676500000000000000000000000000000081525061455d565b9050806001600160a01b031663f3358a3a604051602001613150907f6e6f6465732e696e6465780000000000000000000000000000000000000000008152600b0190565b60408051601f198184030181529082905280516020909101207fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16825260048201526024810186905260440161308a565b61328f604051806103200160405280600015158152602001600081526020016060815260200160001515815260200160006001600160a01b0316815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160006001600160a01b0316815260200160006001600160a01b031681526020016000151581526020016000815260200160006001600160a01b031681525090565b60006132cf6040518060400160405280601181526020017f726f636b65744e6f64655374616b696e6700000000000000000000000000000081525061455d565b905060006133116040518060400160405280601181526020017f726f636b65744e6f64654465706f73697400000000000000000000000000000081525061455d565b905060006133536040518060400160405280601c81526020017f726f636b65744e6f64654469737472696275746f72466163746f72790000000081525061455d565b905060006133956040518060400160405280601581526020017f726f636b65744d696e69706f6f6c4d616e61676572000000000000000000000081525061455d565b905060006133d76040518060400160405280600f81526020017f726f636b6574546f6b656e52455448000000000000000000000000000000000081525061455d565b905060006134196040518060400160405280600e81526020017f726f636b6574546f6b656e52504c00000000000000000000000000000000000081525061455d565b9050600061345b6040518060400160405280601981526020017f726f636b6574546f6b656e52504c4669786564537570706c790000000000000081525061455d565b6001600160a01b038a81166103008b018190526000546040517f5b49ff6200000000000000000000000000000000000000000000000000000000815260048101929092529293506101009092041690635b49ff6290602401602060405180830381865afa1580156134d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134f49190614ef9565b6001600160a01b039081166102808a01526000546040517ffd4125130000000000000000000000000000000000000000000000000000000081528b831660048201526101009091049091169063fd41251390602401602060405180830381865afa158015613566573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061358a9190614ef9565b6001600160a01b03166102a08901526135a28961251e565b151588526135af89610444565b60208901526135bd89612dfa565b60408901526135cb8961256f565b151560608901526135db89611ebf565b60a08901526040517f9961cee40000000000000000000000000000000000000000000000000000000081526001600160a01b038a81166004830152881690639961cee490602401602060405180830381865afa15801561363f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136639190614e5c565b60c08901526040517ff0d19b890000000000000000000000000000000000000000000000000000000081526001600160a01b038a8116600483015288169063f0d19b8990602401602060405180830381865afa1580156136c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136eb9190614e5c565b60e08901526040517f03fa87b40000000000000000000000000000000000000000000000000000000081526001600160a01b038a811660048301528816906303fa87b490602401602060405180830381865afa15801561374f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137739190614e5c565b6101008901526040517f4e58ff6e0000000000000000000000000000000000000000000000000000000081526001600160a01b038a81166004830152881690634e58ff6e90602401602060405180830381865afa1580156137d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137fc9190614e5c565b6101208901526040517fa493e6a20000000000000000000000000000000000000000000000000000000081526001600160a01b038a8116600483015288169063a493e6a290602401602060405180830381865afa158015613861573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138859190614e5c565b6101408901526040517f48aeedf50000000000000000000000000000000000000000000000000000000081526001600160a01b038a811660048301528816906348aeedf590602401602060405180830381865afa1580156138ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061390e9190614e5c565b6101608901526040517ffa2a5b010000000000000000000000000000000000000000000000000000000081526001600160a01b038a8116600483015286169063fa2a5b0190602401602060405180830381865afa158015613973573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139979190614ef9565b6001600160a01b031660808901819052604080517f372d054b000000000000000000000000000000000000000000000000000000008152905182319291829163372d054b916004808201926020929091908290030181865afa158015613a01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a259190614e5c565b6102608b01819052613a379083614eb7565b6102408b01526040517f1ce9ec330000000000000000000000000000000000000000000000000000000081526001600160a01b038c81166004830152871690631ce9ec3390602401602060405180830381865afa158015613a9c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ac09190614e5c565b6101808b01526001600160a01b038b811680316101a08d01526040517f70a082310000000000000000000000000000000000000000000000000000000081526004810191909152908616906370a0823190602401602060405180830381865afa158015613b31573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b559190614e5c565b6101c08b01526040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b038c811660048301528516906370a0823190602401602060405180830381865afa158015613bba573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bde9190614e5c565b6101e08b01526040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b038c811660048301528416906370a0823190602401602060405180830381865afa158015613c43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c679190614e5c565b6102008b01526040517f493c94670000000000000000000000000000000000000000000000000000000081526001600160a01b038c8116600483015289169063493c946790602401602060405180830381865afa158015613ccc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613cf09190614e5c565b6102208b015250979998505050505050505050565b6040518060400160405280601181526020017f726f636b65744e6f64654d616e6167657200000000000000000000000000000081525030613d50826040516020016106399190614dfa565b6001600160a01b0316816001600160a01b031614613db05760405162461bcd60e51b815260206004820152601c60248201527f496e76616c6964206f72206f7574646174656420636f6e74726163740000000060448201526064016104f6565b600080546040517f5b49ff620000000000000000000000000000000000000000000000000000000081526001600160a01b03878116600483015261010090920490911690635b49ff6290602401602060405180830381865afa158015613e1a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e3e9190614ef9565b90506001600160a01b0381163314613ee55760405162461bcd60e51b8152602060048201526044602482018190527f4f6e6c7920612074782066726f6d2061206e6f64652773207769746864726177908201527f616c20616464726573732063616e206368616e676520726577617264206e657460648201527f776f726b00000000000000000000000000000000000000000000000000000000608482015260a4016104f6565b6000613f086040518060600160405280602381526020016151c56023913961455d565b6040517f6dd2623e000000000000000000000000000000000000000000000000000000008152600481018790529091506001600160a01b03821690636dd2623e90602401602060405180830381865afa158015613f69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f8d9190614e3f565b613fd95760405162461bcd60e51b815260206004820152601660248201527f4e6574776f726b206973206e6f7420656e61626c65640000000000000000000060448201526064016104f6565b6040517f6e6f64652e7265776172642e6e6574776f726b0000000000000000000000000060208201526bffffffffffffffffffffffff19606088901b16603382015261403e90604701604051602081830303815290604052805190602001208661472e565b856001600160a01b03167f7c50987deec06761094239e9ff28caa9cfdd305f9c65011c284a0e40cbf4cfdc8660405161407991815260200190565b60405180910390a2505050505050565b6040517f6e6f64652e72706c2e7769746864726177616c2e61646472657373000000000060208201526bffffffffffffffffffffffff19606083901b16603b82015260009081906140dc90604f01610639565b6001600160a01b0316141592915050565b6040517f6e6f64652e65786973747300000000000000000000000000000000000000000060208201526bffffffffffffffffffffffff19606085901b16602b820152839061413d90603f01610493565b6141895760405162461bcd60e51b815260206004820152600c60248201527f496e76616c6964206e6f6465000000000000000000000000000000000000000060448201526064016104f6565b6001600160a01b0383166141df5760405162461bcd60e51b815260206004820152601e60248201527f496e76616c69642052504c207769746864726177616c2061646472657373000060448201526064016104f6565b60006141ea85612fda565b90506001600160a01b038116331461426a5760405162461bcd60e51b815260206004820152603c60248201527f4f6e6c7920612074782066726f6d2061206e6f646527732052504c207769746860448201527f64726177616c20616464726573732063616e207570646174652069740000000060648201526084016104f6565b821561431257614303856040516020016142e891907f6e6f64652e70656e64696e672e72706c2e7769746864726177616c2e6164647281527f6573730000000000000000000000000000000000000000000000000000000000602082015260609190911b6bffffffffffffffffffffffff1916602382015260370190565b60405160208183030381529060405280519060200120614813565b61430d858561488a565b612517565b6125178560405160200161438a91907f6e6f64652e70656e64696e672e72706c2e7769746864726177616c2e6164647281527f6573730000000000000000000000000000000000000000000000000000000000602082015260609190911b6bffffffffffffffffffffffff1916602382015260370190565b6040516020818303038152906040528051906020012085614940565b600080546040517ffd4125130000000000000000000000000000000000000000000000000000000081526001600160a01b0384811660048301526101009092049091169063fd41251390602401612064565b600080546040517f7ae1cfca000000000000000000000000000000000000000000000000000000008152600481018490526101009091046001600160a01b031690637ae1cfca90602401602060405180830381865afa15801561445f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106549190614e3f565b600080546040517fbd02d0f5000000000000000000000000000000000000000000000000000000008152600481018490526101009091046001600160a01b03169063bd02d0f590602401602060405180830381865afa1580156144ea573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106549190614e5c565b600080546040517f21f8a721000000000000000000000000000000000000000000000000000000008152600481018490526101009091046001600160a01b0316906321f8a72190602401612064565b600080614574836040516020016106399190614dfa565b90506001600160a01b0381166106545760405162461bcd60e51b815260206004820152601260248201527f436f6e7472616374206e6f7420666f756e64000000000000000000000000000060448201526064016104f6565b6000546040517fabfdcced0000000000000000000000000000000000000000000000000000000081526004810184905282151560248201526101009091046001600160a01b03169063abfdcced906044015b600060405180830381600087803b15801561463857600080fd5b505af115801561464c573d6000803e3d6000fd5b505050505050565b6000546040517f6e8995500000000000000000000000000000000000000000000000000000000081526101009091046001600160a01b031690636e8995509061461e90859085906004016150f6565b60006146e36040518060400160405280601c81526020017f726f636b65744e6f64654469737472696275746f72466163746f72790000000081525061455d565b6040517f6140c54c0000000000000000000000000000000000000000000000000000000081526001600160a01b03848116600483015291925090821690636140c54c9060240161461e565b6000546040517fe2a4853a00000000000000000000000000000000000000000000000000000000815260048101849052602481018390526101009091046001600160a01b03169063e2a4853a9060440161461e565b6000546040517f986e791a0000000000000000000000000000000000000000000000000000000081526004810183905260609161010090046001600160a01b03169063986e791a90602401600060405180830381865afa1580156147eb573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610654919081019061510f565b6000546040517f0e14a376000000000000000000000000000000000000000000000000000000008152600481018390526101009091046001600160a01b031690630e14a37690602401600060405180830381600087803b15801561487657600080fd5b505af1158015612517573d6000803e3d6000fd5b6040517f6e6f64652e72706c2e7769746864726177616c2e61646472657373000000000060208201526bffffffffffffffffffffffff19606084901b16603b8201526148ef90604f016040516020818303038152906040528051906020012082614940565b806001600160a01b0316826001600160a01b03167f18702dcdad68e2a2d4350dc9f33402b58fd397352dd47a45312fccd5ff1e52a64260405161493491815260200190565b60405180910390a35050565b6000546040517fca446dd9000000000000000000000000000000000000000000000000000000008152600481018490526001600160a01b0383811660248301526101009092049091169063ca446dd99060440161461e565b6001600160a01b03811681146149ad57600080fd5b50565b6000602082840312156149c257600080fd5b81356105b881614998565b600080602083850312156149e057600080fd5b823567ffffffffffffffff808211156149f857600080fd5b818501915085601f830112614a0c57600080fd5b813581811115614a1b57600080fd5b866020828501011115614a2d57600080fd5b60209290920196919550909350505050565b60008060408385031215614a5257600080fd5b50508035926020909101359150565b60005b83811015614a7c578181015183820152602001614a64565b50506000910152565b60008151808452614a9d816020860160208601614a61565b601f01601f19169290920160200192915050565b60006020808301818452808551808352604092508286019150828160051b87010184880160005b83811015614b37577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc089840301855281518051878552614b1a88860182614a85565b918901519489019490945294870194925090860190600101614ad8565b509098975050505050505050565b6020808252825182820181905260009190848201906040850190845b81811015614b865783516001600160a01b031683529284019291840191600101614b61565b50909695505050505050565b80151581146149ad57600080fd5b600060208284031215614bb257600080fd5b81356105b881614b92565b6020815260006105b86020830184614a85565b600060208284031215614be257600080fd5b5035919050565b60208152614bfc60208201835115159052565b6020820151604082015260006040830151610320806060850152614c24610340850183614a85565b91506060850151614c39608086018215159052565b5060808501516001600160a01b03811660a08601525060a085015160c08581019190915285015160e08086019190915285015161010080860191909152850151610120808601919091528501516101408086019190915285015161016080860191909152850151610180808601919091528501516101a0808601919091528501516101c0808601919091528501516101e08086019190915285015161020080860191909152850151610220808601919091528501516102408086019190915285015161026080860191909152850151610280808601919091528501516102a0614d2c818701836001600160a01b03169052565b86015190506102c0614d48868201836001600160a01b03169052565b86015190506102e0614d5d8682018315159052565b86015161030086810191909152909501516001600160a01b031693019290925250919050565b60008060408385031215614d9657600080fd5b8235614da181614998565b946020939093013593505050565b600080600060608486031215614dc457600080fd5b8335614dcf81614998565b92506020840135614ddf81614998565b91506040840135614def81614b92565b809150509250925092565b7f636f6e74726163742e6164647265737300000000000000000000000000000000815260008251614e32816010850160208701614a61565b9190910160100192915050565b600060208284031215614e5157600080fd5b81516105b881614b92565b600060208284031215614e6e57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561065457610654614e75565b8181038181111561065457610654614e75565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060208284031215614f0b57600080fd5b81516105b881614998565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614f7657614f76614e75565b5060010190565b604051601f8201601f1916810167ffffffffffffffff81118282101715614fa657614fa6614eca565b604052919050565b60006020808385031215614fc157600080fd5b825167ffffffffffffffff80821115614fd957600080fd5b818501915085601f830112614fed57600080fd5b815181811115614fff57614fff614eca565b8060051b9150615010848301614f7d565b818152918301840191848101908884111561502a57600080fd5b938501935b838510156150485784518252938501939085019061502f565b98975050505050505050565b808202811582820484141761065457610654614e75565b6000826150a1577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6000602082840312156150e757600080fd5b8151600581106105b857600080fd5b828152604060208201526000611fba6040830184614a85565b60006020828403121561512157600080fd5b815167ffffffffffffffff8082111561513957600080fd5b818401915084601f83011261514d57600080fd5b81518181111561515f5761515f614eca565b6151726020601f19601f84011601614f7d565b915080825285602082850101111561518957600080fd5b61519a816020840160208601614a61565b5094935050505056fe726f636b657444414f50726f746f636f6c53657474696e67734d696e69706f6f6c726f636b657444414f4e6f64655472757374656453657474696e677352657761726473a26469706673582212208ef43a11b82f36494be1b70455eb2dcafd96867e73f138cfd1c8173ae35cacc264736f6c63430008120033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000594Fb75D3dc2DFa0150Ad03F99F97817747dd4E1
-----Decoded View---------------
Arg [0] : _rocketStorageAddress (address): 0x594Fb75D3dc2DFa0150Ad03F99F97817747dd4E1
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000594Fb75D3dc2DFa0150Ad03F99F97817747dd4E1
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.