Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Latest 25 from a total of 248 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Deposit | 24588009 | 22 mins ago | IN | 1.6 ETH | 0.00001456 | ||||
| Withdraw Credit | 24586938 | 3 hrs ago | IN | 0 ETH | 0.00001353 | ||||
| Assign Deposits | 24586779 | 4 hrs ago | IN | 0 ETH | 0.00022735 | ||||
| Deposit | 24586362 | 5 hrs ago | IN | 1 ETH | 0.00003512 | ||||
| Deposit | 24586188 | 6 hrs ago | IN | 0.5492 ETH | 0.00010316 | ||||
| Deposit | 24583012 | 17 hrs ago | IN | 6.87128353 ETH | 0.00036981 | ||||
| Deposit | 24582858 | 17 hrs ago | IN | 8 ETH | 0.00005112 | ||||
| Withdraw Credit | 24582020 | 20 hrs ago | IN | 0 ETH | 0.00001998 | ||||
| Withdraw Credit | 24581945 | 20 hrs ago | IN | 0 ETH | 0.00001951 | ||||
| Deposit | 24581263 | 22 hrs ago | IN | 0.1 ETH | 0.00000745 | ||||
| Deposit | 24581158 | 23 hrs ago | IN | 2.77322148 ETH | 0.00037006 | ||||
| Deposit | 24580755 | 24 hrs ago | IN | 0.3 ETH | 0.00000858 | ||||
| Deposit | 24580626 | 25 hrs ago | IN | 0.1988 ETH | 0.00035558 | ||||
| Assign Deposits | 24580350 | 26 hrs ago | IN | 0 ETH | 0.00015304 | ||||
| Deposit | 24580347 | 26 hrs ago | IN | 79 ETH | 0.00011466 | ||||
| Deposit | 24580328 | 26 hrs ago | IN | 79 ETH | 0.0001492 | ||||
| Deposit | 24580305 | 26 hrs ago | IN | 75 ETH | 0.00011404 | ||||
| Deposit | 24580235 | 26 hrs ago | IN | 2.747 ETH | 0.00001189 | ||||
| Deposit | 24580186 | 26 hrs ago | IN | 50 ETH | 0.0000888 | ||||
| Deposit | 24579690 | 28 hrs ago | IN | 5 ETH | 0.00002991 | ||||
| Deposit | 24579308 | 29 hrs ago | IN | 0.0277 ETH | 0.0000366 | ||||
| Deposit | 24577507 | 35 hrs ago | IN | 1,500 ETH | 0.00082288 | ||||
| Deposit | 24577472 | 35 hrs ago | IN | 1.185 ETH | 0.00002375 | ||||
| Deposit | 24576927 | 37 hrs ago | IN | 0.015 ETH | 0.00038095 | ||||
| Deposit | 24576875 | 37 hrs ago | IN | 0.87 ETH | 0.00002665 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Method | Block |
From
|
|
To
|
||
|---|---|---|---|---|---|---|---|
| Deposit Excess | 24588009 | 22 mins ago | 1.6 ETH | ||||
| Assign Funds | 24587867 | 50 mins ago | 32 ETH | ||||
| Receive Vault Wi... | 24587867 | 50 mins ago | 32 ETH | ||||
| Deposit Ether | 24587867 | 50 mins ago | 24 ETH | ||||
| Node Deposit | 24587867 | 50 mins ago | 24 ETH | ||||
| Assign Funds | 24586900 | 4 hrs ago | 32 ETH | ||||
| Receive Vault Wi... | 24586900 | 4 hrs ago | 32 ETH | ||||
| Assign Funds | 24586900 | 4 hrs ago | 32 ETH | ||||
| Receive Vault Wi... | 24586900 | 4 hrs ago | 32 ETH | ||||
| Assign Funds | 24586900 | 4 hrs ago | 32 ETH | ||||
| Receive Vault Wi... | 24586900 | 4 hrs ago | 32 ETH | ||||
| Deposit Ether | 24586900 | 4 hrs ago | 88 ETH | ||||
| Node Deposit | 24586900 | 4 hrs ago | 88 ETH | ||||
| Assign Funds | 24586894 | 4 hrs ago | 32 ETH | ||||
| Receive Vault Wi... | 24586894 | 4 hrs ago | 32 ETH | ||||
| Assign Funds | 24586894 | 4 hrs ago | 32 ETH | ||||
| Receive Vault Wi... | 24586894 | 4 hrs ago | 32 ETH | ||||
| Deposit Ether | 24586894 | 4 hrs ago | 80 ETH | ||||
| Node Deposit | 24586894 | 4 hrs ago | 80 ETH | ||||
| Assign Funds | 24586888 | 4 hrs ago | 32 ETH | ||||
| Receive Vault Wi... | 24586888 | 4 hrs ago | 32 ETH | ||||
| Assign Funds | 24586888 | 4 hrs ago | 32 ETH | ||||
| Receive Vault Wi... | 24586888 | 4 hrs ago | 32 ETH | ||||
| Assign Funds | 24586888 | 4 hrs ago | 32 ETH | ||||
| Receive Vault Wi... | 24586888 | 4 hrs ago | 32 ETH |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
RocketDepositPool
Compiler Version
v0.8.30+commit.73712a01
Contract Source Code (Solidity Standard Json-Input format)
/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity 0.8.30;
import {SafeCast} from "@openzeppelin4/contracts/utils/math/SafeCast.sol";
import {RocketNetworkBalancesInterface} from "../../interface/network/RocketNetworkBalancesInterface.sol";
import {AddressQueueStorageInterface} from "../../interface/util/AddressQueueStorageInterface.sol";
import {LinkedListStorageInterface} from "../../interface/util/LinkedListStorageInterface.sol";
import {RocketBase} from "../RocketBase.sol";
import {RocketDAOProtocolSettingsDepositInterface} from "../../interface/dao/protocol/settings/RocketDAOProtocolSettingsDepositInterface.sol";
import {RocketDAOProtocolSettingsMinipoolInterface} from "../../interface/dao/protocol/settings/RocketDAOProtocolSettingsMinipoolInterface.sol";
import {RocketDAOProtocolSettingsNetworkInterface} from "../../interface/dao/protocol/settings/RocketDAOProtocolSettingsNetworkInterface.sol";
import {RocketDepositPoolInterface} from "../../interface/deposit/RocketDepositPoolInterface.sol";
import {RocketMegapoolDelegateInterface} from "../../interface/megapool/RocketMegapoolDelegateInterface.sol";
import {RocketMegapoolInterface} from "../../interface/megapool/RocketMegapoolInterface.sol";
import {RocketMinipoolInterface} from "../../interface/minipool/RocketMinipoolInterface.sol";
import {RocketMinipoolQueueInterface} from "../../interface/minipool/RocketMinipoolQueueInterface.sol";
import {RocketNetworkSnapshotsInterface} from "../../interface/network/RocketNetworkSnapshotsInterface.sol";
import {RocketNodeManagerInterface} from "../../interface/node/RocketNodeManagerInterface.sol";
import {RocketStorageInterface} from "../../interface/RocketStorageInterface.sol";
import {RocketTokenRETHInterface} from "../../interface/token/RocketTokenRETHInterface.sol";
import {RocketVaultInterface} from "../../interface/RocketVaultInterface.sol";
import {RocketVaultWithdrawerInterface} from "../../interface/RocketVaultWithdrawerInterface.sol";
import {RocketMegapoolFactoryInterface} from "../../interface/megapool/RocketMegapoolFactoryInterface.sol";
/// @notice Accepts user deposits and mints rETH; handles assignment of deposited ETH to megapools
contract RocketDepositPool is RocketBase, RocketDepositPoolInterface, RocketVaultWithdrawerInterface {
// Constants
uint256 internal constant milliToWei = 10 ** 15;
bytes32 internal constant queueKeyMinipoolVariable = keccak256("minipools.available.variable");
bytes32 internal constant expressQueueNamespace = keccak256("deposit.queue.express");
bytes32 internal constant standardQueueNamespace = keccak256("deposit.queue.standard");
bytes32 internal constant queueMovedKey = keccak256("megapool.queue.moved");
bytes32 internal constant nodeBalanceKey = "deposit.pool.node.balance"; // Note: this is not hashed due to bug in earlier contract
bytes32 internal constant requestedTotalKey = keccak256("deposit.pool.requested.total");
bytes32 internal constant queueIndexKey = keccak256("megapool.queue.index");
// Immutables
RocketVaultInterface immutable internal rocketVault;
RocketTokenRETHInterface immutable internal rocketTokenRETH;
// Events
event DepositReceived(address indexed from, uint256 amount, uint256 time);
event DepositRecycled(address indexed from, uint256 amount, uint256 time);
event DepositAssigned(address indexed minipool, uint256 amount, uint256 time);
event ExcessWithdrawn(address indexed to, uint256 amount, uint256 time);
event FundsRequested(address indexed receiver, uint256 validatorId, uint256 amount, bool expressQueue, uint256 time);
event FundsAssigned(address indexed receiver, uint256 amount, uint256 time);
event QueueExited(address indexed nodeAddress, uint256 time);
event CreditWithdrawn(address indexed nodeAddress, uint256 amount, uint256 time);
// Structs
struct MinipoolAssignment {
address minipoolAddress;
uint256 etherAssigned;
}
// Modifiers
modifier onlyThisLatestContract() {
// Compiler can optimise out this keccak at compile time
require(address(this) == getAddress(keccak256("contract.addressrocketDepositPool")), "Invalid or outdated contract");
_;
}
constructor(RocketStorageInterface _rocketStorageAddress) RocketBase(_rocketStorageAddress) {
version = 4;
// Pre-retrieve non-upgradable contract addresses to save gas
rocketVault = RocketVaultInterface(getContractAddress("rocketVault"));
rocketTokenRETH = RocketTokenRETHInterface(getContractAddress("rocketTokenRETH"));
}
/// @notice Returns the current deposit pool balance
function getBalance() override public view returns (uint256) {
return rocketVault.balanceOf("rocketDepositPool");
}
/// @notice Returns the amount of ETH contributed to the deposit pool by node operators waiting in the queue
function getNodeBalance() override public view returns (uint256) {
return getUint(nodeBalanceKey);
}
/// @notice Returns the user owned portion of the deposit pool
/// @dev Negative indicates more ETH has been "lent" to the deposit pool by node operators in the queue
/// than is available from user deposits
function getUserBalance() override public view returns (int256) {
return int256(getBalance()) - int256(getNodeBalance());
}
/// @notice Returns the credit balance for a given node operator
/// @param _nodeAddress Address of the node operator to query
function getNodeCreditBalance(address _nodeAddress) override public view returns (uint256) {
return getUint(keccak256(abi.encodePacked("node.deposit.credit.balance", _nodeAddress)));
}
/// @notice Excess deposit pool balance (in excess of validator queue)
function getExcessBalance() override public view returns (uint256) {
// Get minipool queue capacity
RocketMinipoolQueueInterface rocketMinipoolQueue = RocketMinipoolQueueInterface(getContractAddress("rocketMinipoolQueue"));
uint256 capacity = rocketMinipoolQueue.getEffectiveCapacity();
capacity += getUint(requestedTotalKey);
uint256 balance = getBalance();
// Calculate and return
if (capacity >= balance) {
return 0;
} else {
return balance - capacity;
}
}
/// @dev Callback required to receive ETH withdrawal from the vault
function receiveVaultWithdrawalETH() override external payable onlyThisLatestContract onlyLatestContract("rocketVault", msg.sender) {}
/// @notice Deposits ETH into Rocket Pool and mints the corresponding amount of rETH to the caller
function deposit() override external payable onlyThisLatestContract {
// Check deposit settings
RocketDAOProtocolSettingsDepositInterface rocketDAOProtocolSettingsDeposit = RocketDAOProtocolSettingsDepositInterface(getContractAddress("rocketDAOProtocolSettingsDeposit"));
require(rocketDAOProtocolSettingsDeposit.getDepositEnabled(), "Deposits into Rocket Pool are currently disabled");
require(msg.value >= rocketDAOProtocolSettingsDeposit.getMinimumDeposit(), "The deposited amount is less than the minimum deposit size");
/*
Check if deposit exceeds limit based on current deposit size and minipool queue capacity.
The deposit pool can, at most, accept a deposit that, after assignments, matches ETH to every minipool in
the queue and leaves the deposit pool with maximumDepositPoolSize ETH.
capacityNeeded = depositPoolBalance + msg.value
maxCapacity = maximumDepositPoolSize + queueEffectiveCapacity
assert(capacityNeeded <= maxCapacity)
*/
uint256 capacityNeeded;
unchecked { // Infeasible overflow
capacityNeeded = getBalance() + msg.value;
}
uint256 maxDepositPoolSize = rocketDAOProtocolSettingsDeposit.getMaximumDepositPoolSize();
if (capacityNeeded > maxDepositPoolSize) {
// Doing a conditional require() instead of a single one optimises for the common
// case where capacityNeeded fits in the deposit pool without looking at the queue
if (rocketDAOProtocolSettingsDeposit.getAssignDepositsEnabled()) {
RocketMinipoolQueueInterface rocketMinipoolQueue = RocketMinipoolQueueInterface(getContractAddress("rocketMinipoolQueue"));
uint256 capacity = rocketMinipoolQueue.getEffectiveCapacity();
capacity += getUint(requestedTotalKey);
require(capacityNeeded <= maxDepositPoolSize + capacity, "The deposit pool size after depositing exceeds the maximum size");
} else {
revert("The deposit pool size after depositing exceeds the maximum size");
}
}
// Calculate deposit fee
unchecked { // depositFee < msg.value
uint256 depositFee = msg.value * rocketDAOProtocolSettingsDeposit.getDepositFee() / calcBase;
uint256 depositNet = msg.value - depositFee;
// Mint rETH to user account
rocketTokenRETH.mint(depositNet, msg.sender);
}
// Emit deposit received event
emit DepositReceived(msg.sender, msg.value, block.timestamp);
// Process deposit
processDeposit();
}
/// @notice Returns the maximum amount that can be accepted into the deposit pool at this time in wei
function getMaximumDepositAmount() override external view returns (uint256) {
RocketDAOProtocolSettingsDepositInterface rocketDAOProtocolSettingsDeposit = RocketDAOProtocolSettingsDepositInterface(getContractAddress("rocketDAOProtocolSettingsDeposit"));
// If deposits are disabled max deposit is 0
if (!rocketDAOProtocolSettingsDeposit.getDepositEnabled()) {
return 0;
}
uint256 depositPoolBalance = getBalance();
uint256 maxCapacity = rocketDAOProtocolSettingsDeposit.getMaximumDepositPoolSize();
// When assignments are enabled, we can accept the max amount plus whatever space is available in the minipool queue
if (rocketDAOProtocolSettingsDeposit.getAssignDepositsEnabled()) {
RocketMinipoolQueueInterface rocketMinipoolQueue = RocketMinipoolQueueInterface(getContractAddress("rocketMinipoolQueue"));
maxCapacity += rocketMinipoolQueue.getEffectiveCapacity();
maxCapacity += getUint(requestedTotalKey);
}
// Check we aren't already over
if (depositPoolBalance >= maxCapacity) {
return 0;
}
return maxCapacity - depositPoolBalance;
}
/// @notice Accepts ETH deposit from the node deposit contract (does not mint rETH)
/// @param _bondAmount The total node deposit amount including any credit balance used
function nodeDeposit(uint256 _bondAmount) override external payable onlyThisLatestContract onlyLatestContract("rocketNodeDeposit", msg.sender) {
// Deposit ETH into the vault
if (msg.value > 0) {
rocketVault.depositEther{value: msg.value}();
}
// Increase recorded node balance
addUint(nodeBalanceKey, _bondAmount);
}
/// @notice Recycle a deposit from a dissolved validator
function recycleDissolvedDeposit() override external payable onlyThisLatestContract onlyRegisteredMinipoolOrMegapool(msg.sender) {
_recycleValue();
}
/// @notice Recycle excess ETH from the rETH token contract
function recycleExcessCollateral() override external payable onlyThisLatestContract onlyLatestContract("rocketTokenRETH", msg.sender) {
_recycleValue();
}
/// @notice Recycle a liquidated RPL stake from a slashed minipool
function recycleLiquidatedStake() override external payable onlyThisLatestContract onlyLatestContract("rocketAuctionManager", msg.sender) {
_recycleValue();
}
/// @dev Recycles msg.value into the deposit pool
function _recycleValue() internal {
// Recycle ETH
emit DepositRecycled(msg.sender, msg.value, block.timestamp);
processDeposit();
}
/// @dev Deposits incoming funds into rETH buffer and excess into vault then performs assignment
function processDeposit() internal {
// Direct deposit ETH to rETH until target collateral is reached
uint256 toReth = _getRethCollateralShortfall();
if (toReth > msg.value) {
toReth = msg.value;
}
uint256 toVault = msg.value - toReth;
if (toReth > 0) {
rocketTokenRETH.depositExcess{value: toReth}();
}
if (toVault > 0) {
rocketVault.depositEther{value: toVault}();
}
// Assign deposits if enabled
_assignByDeposit();
}
/// @dev Returns the shortfall in ETH from the target collateral rate of rETH
function _getRethCollateralShortfall() internal returns (uint256) {
// Load contracts
RocketDAOProtocolSettingsNetworkInterface rocketDAOProtocolSettingsNetwork = RocketDAOProtocolSettingsNetworkInterface(getContractAddress("rocketDAOProtocolSettingsNetwork"));
RocketNetworkBalancesInterface rocketNetworkBalances = RocketNetworkBalancesInterface(getContractAddress("rocketNetworkBalances"));
// Calculate target collateral
uint256 targetCollateralRate = rocketDAOProtocolSettingsNetwork.getTargetRethCollateralRate();
uint256 rocketTokenRETHBalance = address(rocketTokenRETH).balance;
uint256 totalCollateral = rocketNetworkBalances.getTotalETHBalance();
uint256 targetCollateral = totalCollateral * targetCollateralRate / calcBase;
// Calculate shortfall
if (targetCollateral > rocketTokenRETHBalance) {
return targetCollateral - rocketTokenRETHBalance;
}
return 0;
}
/// @notice If deposit assignments are enabled, assigns up to specified number of minipools/megapools
/// @param _max Maximum number of minipools/megapools to assign
function maybeAssignDeposits(uint256 _max) override external onlyThisLatestContract {
require(_max > 0, "Must assign at least 1");
RocketDAOProtocolSettingsDepositInterface rocketDAOProtocolSettingsDeposit = RocketDAOProtocolSettingsDepositInterface(getContractAddress("rocketDAOProtocolSettingsDeposit"));
if (!rocketDAOProtocolSettingsDeposit.getAssignDepositsEnabled()) {
return;
}
_assignDeposits(_max, rocketDAOProtocolSettingsDeposit);
}
/// @notice Assigns up to specified number of minipools or megapools, reverts if assignments are disabled
/// @param _max Maximum number of minipools/megapools to assign
function assignDeposits(uint256 _max) override external onlyThisLatestContract {
require(_max > 0, "Must assign at least 1");
RocketDAOProtocolSettingsDepositInterface rocketDAOProtocolSettingsDeposit = RocketDAOProtocolSettingsDepositInterface(getContractAddress("rocketDAOProtocolSettingsDeposit"));
require(rocketDAOProtocolSettingsDeposit.getAssignDepositsEnabled(), "Deposit assignments are disabled");
_assignDeposits(_max, rocketDAOProtocolSettingsDeposit);
}
/// @dev Assigns up to specified number of minipools or megapools
/// @param _max Maximum number of minipools/megapools to assign
function _assignDeposits(uint256 _max, RocketDAOProtocolSettingsDepositInterface _rocketDAOProtocolSettingsDeposit) internal {
// Get contracts
AddressQueueStorageInterface addressQueueStorage = AddressQueueStorageInterface(getContractAddress("addressQueueStorage"));
// Process minipool queue first
uint256 minipoolQueueLength = addressQueueStorage.getLength(queueKeyMinipoolVariable);
if (minipoolQueueLength > 0) {
if (minipoolQueueLength >= _max) {
_assignMinipools(_max, _rocketDAOProtocolSettingsDeposit);
return;
} else {
unchecked { // _max > minipoolQueueLength
_max -= minipoolQueueLength;
}
_assignMinipools(minipoolQueueLength, _rocketDAOProtocolSettingsDeposit);
}
}
// Assign remainder to megapools
if (_max > 0) {
_assignMegapools(_max, _rocketDAOProtocolSettingsDeposit);
}
}
/// @dev Assigns to minipools/megapools based on `msg.value`, does nothing if assignments are disabled
function _assignByDeposit() internal {
// Get contracts
RocketDAOProtocolSettingsDepositInterface rocketDAOProtocolSettingsDeposit = RocketDAOProtocolSettingsDepositInterface(getContractAddress("rocketDAOProtocolSettingsDeposit"));
// Check if assigning deposits is enabled
if (!rocketDAOProtocolSettingsDeposit.getAssignDepositsEnabled()) {
return;
}
// Continue processing legacy minipool queue until empty
AddressQueueStorageInterface addressQueueStorage = AddressQueueStorageInterface(getContractAddress("addressQueueStorage"));
if (addressQueueStorage.getLength(queueKeyMinipoolVariable) > 0) {
RocketMinipoolQueueInterface rocketMinipoolQueue = RocketMinipoolQueueInterface(getContractAddress("rocketMinipoolQueue"));
_assignMinipoolsByDeposit(rocketMinipoolQueue, rocketDAOProtocolSettingsDeposit);
} else {
// Then assign megapools
_assignMegapoolsByDeposit(rocketDAOProtocolSettingsDeposit);
}
}
/// @dev Assigns a number of minipools based on `msg.value`
function _assignMinipoolsByDeposit(RocketMinipoolQueueInterface _rocketMinipoolQueue, RocketDAOProtocolSettingsDepositInterface _rocketDAOProtocolSettingsDeposit) internal {
// Load contracts
RocketDAOProtocolSettingsMinipoolInterface rocketDAOProtocolSettingsMinipool = RocketDAOProtocolSettingsMinipoolInterface(getContractAddress("rocketDAOProtocolSettingsMinipool"));
// Calculate the number of minipools to assign
uint256 maxAssignments = _rocketDAOProtocolSettingsDeposit.getMaximumDepositAssignments();
uint256 variableDepositAmount = rocketDAOProtocolSettingsMinipool.getVariableDepositAmount();
uint256 scalingCount = msg.value / variableDepositAmount;
uint256 totalEthCount = getBalance() / variableDepositAmount;
uint256 assignments = _rocketDAOProtocolSettingsDeposit.getMaximumDepositSocialisedAssignments() + scalingCount;
if (assignments > totalEthCount) {
assignments = totalEthCount;
}
if (assignments > maxAssignments) {
assignments = maxAssignments;
}
if (assignments > 0) {
_assignMinipools(assignments, _rocketDAOProtocolSettingsDeposit);
}
}
/// @dev Assigns a number of megapools based on `msg.value`
function _assignMegapoolsByDeposit(RocketDAOProtocolSettingsDepositInterface _rocketDAOProtocolSettingsDeposit) internal {
// Calculate the number of megapool validators to assign
uint256 maxAssignments = _rocketDAOProtocolSettingsDeposit.getMaximumDepositAssignments();
uint256 scalingCount = msg.value / 32 ether;
uint256 assignments = _rocketDAOProtocolSettingsDeposit.getMaximumDepositSocialisedAssignments() + scalingCount;
if (assignments > maxAssignments) {
assignments = maxAssignments;
}
if (assignments > 0) {
_assignMegapools(assignments, _rocketDAOProtocolSettingsDeposit);
}
}
/// @dev Assigns up to `_count` number of minipools
/// @param _count Maximum number of entries to assign
function _assignMinipools(uint256 _count, RocketDAOProtocolSettingsDepositInterface _rocketDAOProtocolSettingsDeposit) internal {
// Get contracts
RocketMinipoolQueueInterface rocketMinipoolQueue = RocketMinipoolQueueInterface(getContractAddress("rocketMinipoolQueue"));
RocketDAOProtocolSettingsMinipoolInterface rocketDAOProtocolSettingsMinipool = RocketDAOProtocolSettingsMinipoolInterface(getContractAddress("rocketDAOProtocolSettingsMinipool"));
// Calculate max possible assignments based on current balance
uint256 variableDepositAmount = rocketDAOProtocolSettingsMinipool.getVariableDepositAmount();
uint256 maxPossible = getBalance() / variableDepositAmount;
if (maxPossible == 0) {
return;
}
if (_count > maxPossible) {
_count = maxPossible;
}
// Dequeue minipools
address[] memory minipools = rocketMinipoolQueue.dequeueMinipools(_count);
if (minipools.length > 0) {
// Withdraw ETH from vault
uint256 totalEther = minipools.length * variableDepositAmount;
rocketVault.withdrawEther(totalEther);
uint256 nodeBalanceUsed = 0;
// Loop over minipools and deposit the amount required to reach launch balance
for (uint256 i = 0; i < minipools.length; ++i) {
RocketMinipoolInterface minipool = RocketMinipoolInterface(minipools[i]);
// Assign deposit to minipool
minipool.deposit{value: variableDepositAmount}();
nodeBalanceUsed = nodeBalanceUsed + minipool.getNodeTopUpValue();
// Emit deposit assigned event
emit DepositAssigned(minipools[i], variableDepositAmount, block.timestamp);
}
// Decrease node balance
subUint(nodeBalanceKey, nodeBalanceUsed);
}
}
/// @dev Assigns up to `_count` number of megapools
/// @param _count Maximum number of entries to assign
function _assignMegapools(uint256 _count, RocketDAOProtocolSettingsDepositInterface _rocketDAOProtocolSettingsDeposit) internal {
// Get contracts
LinkedListStorageInterface linkedListStorage = LinkedListStorageInterface(getContractAddress("linkedListStorage"));
// Get required inputs
uint256 expressQueueLength = linkedListStorage.getLength(expressQueueNamespace);
uint256 standardQueueLength = linkedListStorage.getLength(standardQueueNamespace);
uint256 queueIndex = getUint(queueIndexKey);
uint256 expressQueueRate = _rocketDAOProtocolSettingsDeposit.getExpressQueueRate();
// Keep track of changes to applied at the end
uint256 nodeBalanceUsed = 0;
uint256 totalSent = 0;
uint256 vaultBalance = getBalance();
// Keep track of whether heads move
bool expressHeadMoved = false;
bool standardHeadMoved = false;
// Iterate over maximum of `_count` entries
for (uint256 i = 0; i < _count; i++) {
if (expressQueueLength == 0 && standardQueueLength == 0) {
break;
}
// Determine if we are assigning an express queue entry
bool express = queueIndex % (expressQueueRate + 1) != expressQueueRate;
if (express && expressQueueLength == 0) {
express = false;
}
if (!express && standardQueueLength == 0) {
express = true;
}
// Get the entry
bytes32 namespace = getQueueNamespace(express);
LinkedListStorageInterface.DepositQueueValue memory head = linkedListStorage.peekItem(namespace);
uint256 ethRequired = head.requestedValue * milliToWei;
// Check if we have enough available to assign
if (vaultBalance < ethRequired) {
break;
}
// Withdraw the funds from the vault
rocketVault.withdrawEther(ethRequired);
vaultBalance -= ethRequired;
// Assign funds and dequeue megapool
RocketMegapoolInterface(head.receiver).assignFunds{value: ethRequired}(head.validatorId);
emit FundsAssigned(head.receiver, ethRequired, block.timestamp);
linkedListStorage.dequeueItem(namespace);
// Account for node balance
unchecked { // Infeasible overflows and impossible underflows
nodeBalanceUsed += head.suppliedValue * milliToWei;
totalSent += ethRequired;
// Update counts for next iteration
queueIndex += 1;
if (express) {
expressQueueLength -= 1;
expressHeadMoved = true;
} else {
standardQueueLength -= 1;
standardHeadMoved = true;
}
}
}
// Store state changes
subUint(nodeBalanceKey, nodeBalanceUsed);
setUint(queueIndexKey, queueIndex);
subUint(requestedTotalKey, totalSent);
_setQueueMoved(expressHeadMoved, standardHeadMoved);
}
/// @dev Stores block number when the queues moved
function _setQueueMoved(bool expressHeadMoved, bool standardHeadMoved) internal {
uint256 packed = getUint(queueMovedKey);
uint128 express = expressHeadMoved ? uint128(block.number) : uint128(packed >> 0);
uint128 standard = standardHeadMoved ? uint128(block.number) : uint128(packed >> 128);
packed = express << 0;
packed |= uint256(standard) << 128;
setUint(queueMovedKey, packed);
}
/// @dev Withdraw excess deposit pool balance for rETH collateral
/// @param _amount The amount of excess ETH to withdraw
function withdrawExcessBalance(uint256 _amount) override external onlyThisLatestContract onlyLatestContract("rocketTokenRETH", msg.sender) {
// Check amount
require(_amount <= getExcessBalance(), "Insufficient excess balance for withdrawal");
// Withdraw ETH from vault
rocketVault.withdrawEther(_amount);
// Transfer to rETH contract
rocketTokenRETH.depositExcess{value: _amount}();
// Emit excess withdrawn event
emit ExcessWithdrawn(msg.sender, _amount, block.timestamp);
}
/// @notice Requests funds from the deposit queue by a megapool, places the request in the relevant queue
/// @param _bondAmount The bond amount supplied by the NO for the fund request
/// @param _validatorId The megapool-managed ID of the validator requesting funds
/// @param _amount The amount of ETH requested by the node operator
/// @param _expressQueue Whether to consume an express ticket to be placed in the express queue
function requestFunds(uint256 _bondAmount, uint32 _validatorId, uint256 _amount, bool _expressQueue) external onlyRegisteredMegapool(msg.sender) onlyThisLatestContract {
// Validate arguments
require(_bondAmount % milliToWei == 0, "Invalid supplied amount");
require(_amount % milliToWei == 0, "Invalid requested amount");
// Use an express ticket if requested
address nodeAddress = RocketMegapoolInterface(msg.sender).getNodeAddress();
RocketNodeManagerInterface rocketNodeManager = RocketNodeManagerInterface(getContractAddress("rocketNodeManager"));
if (_expressQueue) {
rocketNodeManager.useExpressTicket(nodeAddress);
} else {
rocketNodeManager.provisionExpressTickets(nodeAddress);
}
// Enqueue megapool
bytes32 namespace = getQueueNamespace(_expressQueue);
LinkedListStorageInterface.DepositQueueValue memory value = LinkedListStorageInterface.DepositQueueValue({
receiver: msg.sender, // Megapool address
validatorId: _validatorId, // Incrementing id per validator in a megapool
suppliedValue: SafeCast.toUint32(_bondAmount / milliToWei), // NO bond amount
requestedValue: SafeCast.toUint32(_amount / milliToWei) // Amount being requested
});
LinkedListStorageInterface linkedListStorage = LinkedListStorageInterface(getContractAddress("linkedListStorage"));
linkedListStorage.enqueueItem(namespace, value);
// Increase requested balance
addUint(requestedTotalKey, _amount);
// Check if head moved
if (_expressQueue) {
uint256 expressQueueLength = linkedListStorage.getLength(expressQueueNamespace);
if (expressQueueLength == 1) {
_setQueueMoved(true, false);
}
} else {
uint256 standardQueueLength = linkedListStorage.getLength(standardQueueNamespace);
if (standardQueueLength == 1) {
_setQueueMoved(false, true);
}
}
{
// Update collateral balances
_increaseETHBonded(nodeAddress, _bondAmount);
_increaseETHBorrowed(nodeAddress, _amount - _bondAmount);
}
// Emit event
emit FundsRequested(msg.sender, _validatorId, _amount, _expressQueue, block.timestamp);
}
/// @dev Called from a megapool to remove an entry in the validator queue and returns funds to node by credit mechanism
/// @param _validatorId Internal ID of the validator to be removed
/// @param _expressQueue Whether the entry is in the express queue or not
function exitQueue(address _nodeAddress, uint32 _validatorId, bool _expressQueue) external onlyRegisteredMegapool(msg.sender) onlyThisLatestContract {
LinkedListStorageInterface linkedListStorage = LinkedListStorageInterface(getContractAddress("linkedListStorage"));
LinkedListStorageInterface.DepositQueueKey memory key = LinkedListStorageInterface.DepositQueueKey({
receiver: msg.sender,
validatorId: _validatorId
});
bytes32 namespace = getQueueNamespace(_expressQueue);
uint256 index = linkedListStorage.getIndexOf(namespace, key);
LinkedListStorageInterface.DepositQueueValue memory value = linkedListStorage.getItem(namespace, index);
bool isAtHead = linkedListStorage.getHeadIndex(namespace) == index;
linkedListStorage.removeItem(namespace, key);
// Perform balance accounting
subUint(requestedTotalKey, value.requestedValue * milliToWei);
if (_expressQueue) {
// Refund express ticket
RocketNodeManagerInterface rocketNodeManager = RocketNodeManagerInterface(getContractAddress("rocketNodeManager"));
rocketNodeManager.refundExpressTicket(_nodeAddress);
// Update head moved block
if (isAtHead) {
_setQueueMoved(true, false);
}
} else {
// Update head moved block
if (isAtHead) {
_setQueueMoved(false, true);
}
}
// Remove bond from node balance
uint256 nodeBalanceUsed = value.suppliedValue * milliToWei;
subUint(nodeBalanceKey, nodeBalanceUsed);
// Emit event
emit QueueExited(_nodeAddress, block.timestamp);
}
/// @dev Called from megapool to increase a node operator's credit
function applyCredit(address _nodeAddress, uint256 _amount) override external onlyRegisteredMegapool(msg.sender) onlyThisLatestContract {
// Add to node's credit for the amount supplied
addUint(keccak256(abi.encodePacked("node.deposit.credit.balance", _nodeAddress)), _amount);
}
/// @notice Allows node operator to withdraw any ETH credit they have as rETH
/// @param _amount Amount in ETH to withdraw
function withdrawCredit(uint256 _amount) override external onlyRegisteredNode(msg.sender) onlyThisLatestContract {
address withdrawalAddress = rocketStorage.getNodeWithdrawalAddress(msg.sender);
_withdrawCreditFor(msg.sender, withdrawalAddress, _amount);
}
/// @notice Allows node operator to withdraw any ETH credit they have as rETH from their withdrawal address
/// @param _nodeAddress Address of the node operator
/// @param _amount Amount in ETH to withdraw
function withdrawCreditFor(address _nodeAddress, uint256 _amount) override public onlyRegisteredNode(_nodeAddress) onlyThisLatestContract {
// Check caller
address withdrawalAddress = rocketStorage.getNodeWithdrawalAddress(_nodeAddress);
require(msg.sender == withdrawalAddress, "Must be called from withdrawal address");
// Withdraw credit
_withdrawCreditFor(_nodeAddress, withdrawalAddress, _amount);
}
/// @dev Withdraws credit from a given node operator as rETH
function _withdrawCreditFor(address _nodeAddress, address _recipient, uint256 _amount) internal {
// Check deposits are enabled
RocketDAOProtocolSettingsDepositInterface rocketDAOProtocolSettingsDeposit = RocketDAOProtocolSettingsDepositInterface(getContractAddress("rocketDAOProtocolSettingsDeposit"));
require(rocketDAOProtocolSettingsDeposit.getDepositEnabled(), "Deposits into Rocket Pool are currently disabled");
// Ensure no debt exists on the node operator's megapool
RocketMegapoolFactoryInterface rocketMegapoolFactory = RocketMegapoolFactoryInterface(getContractAddress("rocketMegapoolFactory"));
require(rocketMegapoolFactory.getMegapoolDeployed(_nodeAddress), "Megapool must be deployed");
RocketMegapoolDelegateInterface megapool = RocketMegapoolDelegateInterface(rocketMegapoolFactory.getExpectedAddress(_nodeAddress));
require(megapool.getDebt() == 0, "Cannot withdraw credit while debt exists");
// Check node operator has sufficient credit
bytes32 creditKey = keccak256(abi.encodePacked("node.deposit.credit.balance", _nodeAddress));
uint256 credit = getUint(creditKey);
require(credit >= _amount, "Amount exceeds credit available");
// Account for balance changes
subUint(creditKey, _amount);
// Note: The funds are already stored in RocketVault under RocketDepositPool so no ETH transfer is required
RocketNodeManagerInterface rocketNodeManager = RocketNodeManagerInterface(getContractAddress("rocketNodeManager"));
// Calculate deposit fee
unchecked { // depositFee < msg.value
uint256 depositFee = _amount * rocketDAOProtocolSettingsDeposit.getDepositFee() / calcBase;
uint256 depositNet = _amount - depositFee;
// Mint rETH to recipient address
rocketTokenRETH.mint(depositNet, _recipient);
}
// Emit event
emit CreditWithdrawn(_nodeAddress, _amount, block.timestamp);
}
/// @notice Gets the receiver next to be assigned and whether it can be assigned immediately
/// @dev During the transition period from the legacy minipool queue, this will always return null address
/// @return receiver Address of the receiver of the next assignment or null address for an empty queue
/// @return assignmentPossible Whether there is enough funds in the pool to perform an assignment now
/// @return headMovedBlock The block at which the receiver entered the top of the queue
function getQueueTop() override external view returns (address receiver, bool assignmentPossible, uint256 headMovedBlock) {
// If legacy queue is still being processed, return null address
AddressQueueStorageInterface addressQueueStorage = AddressQueueStorageInterface(getContractAddress("addressQueueStorage"));
if (addressQueueStorage.getLength(queueKeyMinipoolVariable) > 0) {
return (address(0x0), false, 0);
}
// Get contracts
LinkedListStorageInterface linkedListStorage = LinkedListStorageInterface(getContractAddress("linkedListStorage"));
RocketDAOProtocolSettingsDepositInterface rocketDAOProtocolSettingsDeposit = RocketDAOProtocolSettingsDepositInterface(getContractAddress("rocketDAOProtocolSettingsDeposit"));
uint256 expressQueueLength = linkedListStorage.getLength(expressQueueNamespace);
uint256 standardQueueLength = linkedListStorage.getLength(standardQueueNamespace);
// If both queues are empty, return null address
if (expressQueueLength == 0 && standardQueueLength == 0) {
return (address(0x0), false, 0);
}
uint256 queueIndex = getUint(queueIndexKey);
uint256 expressQueueRate = rocketDAOProtocolSettingsDeposit.getExpressQueueRate();
bool express = queueIndex % (expressQueueRate + 1) != expressQueueRate;
if (express && expressQueueLength == 0) {
express = false;
}
if (!express && standardQueueLength == 0) {
express = true;
}
// Check if enough value is in the deposit pool to assign the requested value
bytes32 namespace = getQueueNamespace(express);
LinkedListStorageInterface.DepositQueueValue memory head = linkedListStorage.peekItem(namespace);
assignmentPossible = rocketVault.balanceOf("rocketDepositPool") >= head.requestedValue * milliToWei;
// Check assignments are enabled
if (!rocketDAOProtocolSettingsDeposit.getAssignDepositsEnabled()) {
assignmentPossible = false;
}
// Retrieve the block at which the entry at the top of the queue got to that position
uint256 packed = getUint(queueMovedKey);
if (express) {
headMovedBlock = uint128(packed);
} else {
headMovedBlock = uint128(packed >> 128);
}
return (head.receiver, assignmentPossible, headMovedBlock);
}
/// @notice Retrieves the queue index (used for deciding whether to assign express or standard queue next)
function getQueueIndex() override external view returns (uint256) {
return getUint(queueIndexKey);
}
/// @notice Returns the number of minipools in the queue
function getMinipoolQueueLength() override public view returns (uint256) {
AddressQueueStorageInterface addressQueueStorage = AddressQueueStorageInterface(getContractAddress("addressQueueStorage"));
return addressQueueStorage.getLength(queueKeyMinipoolVariable);
}
/// @notice Returns the number of megapool validators in the express queue
function getExpressQueueLength() override public view returns (uint256) {
LinkedListStorageInterface linkedListStorage = LinkedListStorageInterface(getContractAddress("linkedListStorage"));
return linkedListStorage.getLength(expressQueueNamespace);
}
/// @notice Returns the number of megapool validators in the standard queue
function getStandardQueueLength() override public view returns (uint256) {
LinkedListStorageInterface linkedListStorage = LinkedListStorageInterface(getContractAddress("linkedListStorage"));
return linkedListStorage.getLength(standardQueueNamespace);
}
/// @notice Returns the total number of minipools/megapools in the queue
function getTotalQueueLength() override external view returns (uint256) {
return getMinipoolQueueLength() + getExpressQueueLength() + getStandardQueueLength();
}
/// @dev Convenience method to return queue key for express and non-express queues
function getQueueNamespace(bool _expressQueue) internal pure returns (bytes32) {
if (_expressQueue) {
return expressQueueNamespace;
}
return standardQueueNamespace;
}
/// @dev Called by a megapool during a bond reduction to adjust its capital ratio
function reduceBond(address _nodeAddress, uint256 _amount) override external onlyRegisteredMegapool(msg.sender) onlyThisLatestContract {
// Update collateral balances
_increaseETHBorrowed(_nodeAddress, _amount);
_decreaseETHBonded(_nodeAddress, _amount);
}
/// @dev Called by a megapool when exiting to handle change in capital ratio
function fundsReturned(address _nodeAddress, uint256 _nodeAmount, uint256 _userAmount) override external onlyRegisteredMegapool(msg.sender) onlyThisLatestContract {
// Update collateral balances
_decreaseETHBonded(_nodeAddress, _nodeAmount);
_decreaseETHBorrowed(_nodeAddress, _userAmount);
}
/// @dev Increases the amount of ETH supplied by a node operator as bond
function _increaseETHBonded(address _nodeAddress, uint256 _amount) internal {
RocketNetworkSnapshotsInterface rocketNetworkSnapshots = RocketNetworkSnapshotsInterface(getContractAddress("rocketNetworkSnapshots"));
bytes32 key = keccak256(abi.encodePacked("megapool.eth.provided.node.amount", _nodeAddress));
uint256 ethBonded = uint256(rocketNetworkSnapshots.latestValue(key)) + _amount;
rocketNetworkSnapshots.push(key, uint224(ethBonded));
}
/// @dev Increases the amount of ETH borrowed by a node operator
function _increaseETHBorrowed(address _nodeAddress, uint256 _amount) internal {
bytes32 key = keccak256(abi.encodePacked("megapool.eth.matched.node.amount", _nodeAddress));
addUint(key, _amount);
}
/// @dev Decreases the amount of ETH bonded by a node operator as bond
function _decreaseETHBonded(address _nodeAddress, uint256 _amount) internal {
RocketNetworkSnapshotsInterface rocketNetworkSnapshots = RocketNetworkSnapshotsInterface(getContractAddress("rocketNetworkSnapshots"));
bytes32 key = keccak256(abi.encodePacked("megapool.eth.provided.node.amount", _nodeAddress));
uint256 ethBonded = uint256(rocketNetworkSnapshots.latestValue(key)) - _amount;
rocketNetworkSnapshots.push(key, uint224(ethBonded));
}
/// @dev Decreases the amount of ETH borrowed by a node operator
function _decreaseETHBorrowed(address _nodeAddress, uint256 _amount) internal {
bytes32 key = keccak256(abi.encodePacked("megapool.eth.matched.node.amount", _nodeAddress));
subUint(key, _amount);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)
// This file was procedurally generated from scripts/generate/templates/SafeCast.js.
pragma solidity ^0.8.0;
/**
* @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow
* checks.
*
* Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
* easily result in undesired exploitation or bugs, since developers usually
* assume that overflows raise errors. `SafeCast` restores this intuition by
* reverting the transaction when such an operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*
* Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing
* all math on `uint256` and `int256` and then downcasting.
*/
library SafeCast {
/**
* @dev Returns the downcasted uint248 from uint256, reverting on
* overflow (when the input is greater than largest uint248).
*
* Counterpart to Solidity's `uint248` operator.
*
* Requirements:
*
* - input must fit into 248 bits
*
* _Available since v4.7._
*/
function toUint248(uint256 value) internal pure returns (uint248) {
require(value <= type(uint248).max, "SafeCast: value doesn't fit in 248 bits");
return uint248(value);
}
/**
* @dev Returns the downcasted uint240 from uint256, reverting on
* overflow (when the input is greater than largest uint240).
*
* Counterpart to Solidity's `uint240` operator.
*
* Requirements:
*
* - input must fit into 240 bits
*
* _Available since v4.7._
*/
function toUint240(uint256 value) internal pure returns (uint240) {
require(value <= type(uint240).max, "SafeCast: value doesn't fit in 240 bits");
return uint240(value);
}
/**
* @dev Returns the downcasted uint232 from uint256, reverting on
* overflow (when the input is greater than largest uint232).
*
* Counterpart to Solidity's `uint232` operator.
*
* Requirements:
*
* - input must fit into 232 bits
*
* _Available since v4.7._
*/
function toUint232(uint256 value) internal pure returns (uint232) {
require(value <= type(uint232).max, "SafeCast: value doesn't fit in 232 bits");
return uint232(value);
}
/**
* @dev Returns the downcasted uint224 from uint256, reverting on
* overflow (when the input is greater than largest uint224).
*
* Counterpart to Solidity's `uint224` operator.
*
* Requirements:
*
* - input must fit into 224 bits
*
* _Available since v4.2._
*/
function toUint224(uint256 value) internal pure returns (uint224) {
require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits");
return uint224(value);
}
/**
* @dev Returns the downcasted uint216 from uint256, reverting on
* overflow (when the input is greater than largest uint216).
*
* Counterpart to Solidity's `uint216` operator.
*
* Requirements:
*
* - input must fit into 216 bits
*
* _Available since v4.7._
*/
function toUint216(uint256 value) internal pure returns (uint216) {
require(value <= type(uint216).max, "SafeCast: value doesn't fit in 216 bits");
return uint216(value);
}
/**
* @dev Returns the downcasted uint208 from uint256, reverting on
* overflow (when the input is greater than largest uint208).
*
* Counterpart to Solidity's `uint208` operator.
*
* Requirements:
*
* - input must fit into 208 bits
*
* _Available since v4.7._
*/
function toUint208(uint256 value) internal pure returns (uint208) {
require(value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits");
return uint208(value);
}
/**
* @dev Returns the downcasted uint200 from uint256, reverting on
* overflow (when the input is greater than largest uint200).
*
* Counterpart to Solidity's `uint200` operator.
*
* Requirements:
*
* - input must fit into 200 bits
*
* _Available since v4.7._
*/
function toUint200(uint256 value) internal pure returns (uint200) {
require(value <= type(uint200).max, "SafeCast: value doesn't fit in 200 bits");
return uint200(value);
}
/**
* @dev Returns the downcasted uint192 from uint256, reverting on
* overflow (when the input is greater than largest uint192).
*
* Counterpart to Solidity's `uint192` operator.
*
* Requirements:
*
* - input must fit into 192 bits
*
* _Available since v4.7._
*/
function toUint192(uint256 value) internal pure returns (uint192) {
require(value <= type(uint192).max, "SafeCast: value doesn't fit in 192 bits");
return uint192(value);
}
/**
* @dev Returns the downcasted uint184 from uint256, reverting on
* overflow (when the input is greater than largest uint184).
*
* Counterpart to Solidity's `uint184` operator.
*
* Requirements:
*
* - input must fit into 184 bits
*
* _Available since v4.7._
*/
function toUint184(uint256 value) internal pure returns (uint184) {
require(value <= type(uint184).max, "SafeCast: value doesn't fit in 184 bits");
return uint184(value);
}
/**
* @dev Returns the downcasted uint176 from uint256, reverting on
* overflow (when the input is greater than largest uint176).
*
* Counterpart to Solidity's `uint176` operator.
*
* Requirements:
*
* - input must fit into 176 bits
*
* _Available since v4.7._
*/
function toUint176(uint256 value) internal pure returns (uint176) {
require(value <= type(uint176).max, "SafeCast: value doesn't fit in 176 bits");
return uint176(value);
}
/**
* @dev Returns the downcasted uint168 from uint256, reverting on
* overflow (when the input is greater than largest uint168).
*
* Counterpart to Solidity's `uint168` operator.
*
* Requirements:
*
* - input must fit into 168 bits
*
* _Available since v4.7._
*/
function toUint168(uint256 value) internal pure returns (uint168) {
require(value <= type(uint168).max, "SafeCast: value doesn't fit in 168 bits");
return uint168(value);
}
/**
* @dev Returns the downcasted uint160 from uint256, reverting on
* overflow (when the input is greater than largest uint160).
*
* Counterpart to Solidity's `uint160` operator.
*
* Requirements:
*
* - input must fit into 160 bits
*
* _Available since v4.7._
*/
function toUint160(uint256 value) internal pure returns (uint160) {
require(value <= type(uint160).max, "SafeCast: value doesn't fit in 160 bits");
return uint160(value);
}
/**
* @dev Returns the downcasted uint152 from uint256, reverting on
* overflow (when the input is greater than largest uint152).
*
* Counterpart to Solidity's `uint152` operator.
*
* Requirements:
*
* - input must fit into 152 bits
*
* _Available since v4.7._
*/
function toUint152(uint256 value) internal pure returns (uint152) {
require(value <= type(uint152).max, "SafeCast: value doesn't fit in 152 bits");
return uint152(value);
}
/**
* @dev Returns the downcasted uint144 from uint256, reverting on
* overflow (when the input is greater than largest uint144).
*
* Counterpart to Solidity's `uint144` operator.
*
* Requirements:
*
* - input must fit into 144 bits
*
* _Available since v4.7._
*/
function toUint144(uint256 value) internal pure returns (uint144) {
require(value <= type(uint144).max, "SafeCast: value doesn't fit in 144 bits");
return uint144(value);
}
/**
* @dev Returns the downcasted uint136 from uint256, reverting on
* overflow (when the input is greater than largest uint136).
*
* Counterpart to Solidity's `uint136` operator.
*
* Requirements:
*
* - input must fit into 136 bits
*
* _Available since v4.7._
*/
function toUint136(uint256 value) internal pure returns (uint136) {
require(value <= type(uint136).max, "SafeCast: value doesn't fit in 136 bits");
return uint136(value);
}
/**
* @dev Returns the downcasted uint128 from uint256, reverting on
* overflow (when the input is greater than largest uint128).
*
* Counterpart to Solidity's `uint128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*
* _Available since v2.5._
*/
function toUint128(uint256 value) internal pure returns (uint128) {
require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits");
return uint128(value);
}
/**
* @dev Returns the downcasted uint120 from uint256, reverting on
* overflow (when the input is greater than largest uint120).
*
* Counterpart to Solidity's `uint120` operator.
*
* Requirements:
*
* - input must fit into 120 bits
*
* _Available since v4.7._
*/
function toUint120(uint256 value) internal pure returns (uint120) {
require(value <= type(uint120).max, "SafeCast: value doesn't fit in 120 bits");
return uint120(value);
}
/**
* @dev Returns the downcasted uint112 from uint256, reverting on
* overflow (when the input is greater than largest uint112).
*
* Counterpart to Solidity's `uint112` operator.
*
* Requirements:
*
* - input must fit into 112 bits
*
* _Available since v4.7._
*/
function toUint112(uint256 value) internal pure returns (uint112) {
require(value <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits");
return uint112(value);
}
/**
* @dev Returns the downcasted uint104 from uint256, reverting on
* overflow (when the input is greater than largest uint104).
*
* Counterpart to Solidity's `uint104` operator.
*
* Requirements:
*
* - input must fit into 104 bits
*
* _Available since v4.7._
*/
function toUint104(uint256 value) internal pure returns (uint104) {
require(value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits");
return uint104(value);
}
/**
* @dev Returns the downcasted uint96 from uint256, reverting on
* overflow (when the input is greater than largest uint96).
*
* Counterpart to Solidity's `uint96` operator.
*
* Requirements:
*
* - input must fit into 96 bits
*
* _Available since v4.2._
*/
function toUint96(uint256 value) internal pure returns (uint96) {
require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits");
return uint96(value);
}
/**
* @dev Returns the downcasted uint88 from uint256, reverting on
* overflow (when the input is greater than largest uint88).
*
* Counterpart to Solidity's `uint88` operator.
*
* Requirements:
*
* - input must fit into 88 bits
*
* _Available since v4.7._
*/
function toUint88(uint256 value) internal pure returns (uint88) {
require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits");
return uint88(value);
}
/**
* @dev Returns the downcasted uint80 from uint256, reverting on
* overflow (when the input is greater than largest uint80).
*
* Counterpart to Solidity's `uint80` operator.
*
* Requirements:
*
* - input must fit into 80 bits
*
* _Available since v4.7._
*/
function toUint80(uint256 value) internal pure returns (uint80) {
require(value <= type(uint80).max, "SafeCast: value doesn't fit in 80 bits");
return uint80(value);
}
/**
* @dev Returns the downcasted uint72 from uint256, reverting on
* overflow (when the input is greater than largest uint72).
*
* Counterpart to Solidity's `uint72` operator.
*
* Requirements:
*
* - input must fit into 72 bits
*
* _Available since v4.7._
*/
function toUint72(uint256 value) internal pure returns (uint72) {
require(value <= type(uint72).max, "SafeCast: value doesn't fit in 72 bits");
return uint72(value);
}
/**
* @dev Returns the downcasted uint64 from uint256, reverting on
* overflow (when the input is greater than largest uint64).
*
* Counterpart to Solidity's `uint64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*
* _Available since v2.5._
*/
function toUint64(uint256 value) internal pure returns (uint64) {
require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits");
return uint64(value);
}
/**
* @dev Returns the downcasted uint56 from uint256, reverting on
* overflow (when the input is greater than largest uint56).
*
* Counterpart to Solidity's `uint56` operator.
*
* Requirements:
*
* - input must fit into 56 bits
*
* _Available since v4.7._
*/
function toUint56(uint256 value) internal pure returns (uint56) {
require(value <= type(uint56).max, "SafeCast: value doesn't fit in 56 bits");
return uint56(value);
}
/**
* @dev Returns the downcasted uint48 from uint256, reverting on
* overflow (when the input is greater than largest uint48).
*
* Counterpart to Solidity's `uint48` operator.
*
* Requirements:
*
* - input must fit into 48 bits
*
* _Available since v4.7._
*/
function toUint48(uint256 value) internal pure returns (uint48) {
require(value <= type(uint48).max, "SafeCast: value doesn't fit in 48 bits");
return uint48(value);
}
/**
* @dev Returns the downcasted uint40 from uint256, reverting on
* overflow (when the input is greater than largest uint40).
*
* Counterpart to Solidity's `uint40` operator.
*
* Requirements:
*
* - input must fit into 40 bits
*
* _Available since v4.7._
*/
function toUint40(uint256 value) internal pure returns (uint40) {
require(value <= type(uint40).max, "SafeCast: value doesn't fit in 40 bits");
return uint40(value);
}
/**
* @dev Returns the downcasted uint32 from uint256, reverting on
* overflow (when the input is greater than largest uint32).
*
* Counterpart to Solidity's `uint32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*
* _Available since v2.5._
*/
function toUint32(uint256 value) internal pure returns (uint32) {
require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits");
return uint32(value);
}
/**
* @dev Returns the downcasted uint24 from uint256, reverting on
* overflow (when the input is greater than largest uint24).
*
* Counterpart to Solidity's `uint24` operator.
*
* Requirements:
*
* - input must fit into 24 bits
*
* _Available since v4.7._
*/
function toUint24(uint256 value) internal pure returns (uint24) {
require(value <= type(uint24).max, "SafeCast: value doesn't fit in 24 bits");
return uint24(value);
}
/**
* @dev Returns the downcasted uint16 from uint256, reverting on
* overflow (when the input is greater than largest uint16).
*
* Counterpart to Solidity's `uint16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*
* _Available since v2.5._
*/
function toUint16(uint256 value) internal pure returns (uint16) {
require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits");
return uint16(value);
}
/**
* @dev Returns the downcasted uint8 from uint256, reverting on
* overflow (when the input is greater than largest uint8).
*
* Counterpart to Solidity's `uint8` operator.
*
* Requirements:
*
* - input must fit into 8 bits
*
* _Available since v2.5._
*/
function toUint8(uint256 value) internal pure returns (uint8) {
require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits");
return uint8(value);
}
/**
* @dev Converts a signed int256 into an unsigned uint256.
*
* Requirements:
*
* - input must be greater than or equal to 0.
*
* _Available since v3.0._
*/
function toUint256(int256 value) internal pure returns (uint256) {
require(value >= 0, "SafeCast: value must be positive");
return uint256(value);
}
/**
* @dev Returns the downcasted int248 from int256, reverting on
* overflow (when the input is less than smallest int248 or
* greater than largest int248).
*
* Counterpart to Solidity's `int248` operator.
*
* Requirements:
*
* - input must fit into 248 bits
*
* _Available since v4.7._
*/
function toInt248(int256 value) internal pure returns (int248 downcasted) {
downcasted = int248(value);
require(downcasted == value, "SafeCast: value doesn't fit in 248 bits");
}
/**
* @dev Returns the downcasted int240 from int256, reverting on
* overflow (when the input is less than smallest int240 or
* greater than largest int240).
*
* Counterpart to Solidity's `int240` operator.
*
* Requirements:
*
* - input must fit into 240 bits
*
* _Available since v4.7._
*/
function toInt240(int256 value) internal pure returns (int240 downcasted) {
downcasted = int240(value);
require(downcasted == value, "SafeCast: value doesn't fit in 240 bits");
}
/**
* @dev Returns the downcasted int232 from int256, reverting on
* overflow (when the input is less than smallest int232 or
* greater than largest int232).
*
* Counterpart to Solidity's `int232` operator.
*
* Requirements:
*
* - input must fit into 232 bits
*
* _Available since v4.7._
*/
function toInt232(int256 value) internal pure returns (int232 downcasted) {
downcasted = int232(value);
require(downcasted == value, "SafeCast: value doesn't fit in 232 bits");
}
/**
* @dev Returns the downcasted int224 from int256, reverting on
* overflow (when the input is less than smallest int224 or
* greater than largest int224).
*
* Counterpart to Solidity's `int224` operator.
*
* Requirements:
*
* - input must fit into 224 bits
*
* _Available since v4.7._
*/
function toInt224(int256 value) internal pure returns (int224 downcasted) {
downcasted = int224(value);
require(downcasted == value, "SafeCast: value doesn't fit in 224 bits");
}
/**
* @dev Returns the downcasted int216 from int256, reverting on
* overflow (when the input is less than smallest int216 or
* greater than largest int216).
*
* Counterpart to Solidity's `int216` operator.
*
* Requirements:
*
* - input must fit into 216 bits
*
* _Available since v4.7._
*/
function toInt216(int256 value) internal pure returns (int216 downcasted) {
downcasted = int216(value);
require(downcasted == value, "SafeCast: value doesn't fit in 216 bits");
}
/**
* @dev Returns the downcasted int208 from int256, reverting on
* overflow (when the input is less than smallest int208 or
* greater than largest int208).
*
* Counterpart to Solidity's `int208` operator.
*
* Requirements:
*
* - input must fit into 208 bits
*
* _Available since v4.7._
*/
function toInt208(int256 value) internal pure returns (int208 downcasted) {
downcasted = int208(value);
require(downcasted == value, "SafeCast: value doesn't fit in 208 bits");
}
/**
* @dev Returns the downcasted int200 from int256, reverting on
* overflow (when the input is less than smallest int200 or
* greater than largest int200).
*
* Counterpart to Solidity's `int200` operator.
*
* Requirements:
*
* - input must fit into 200 bits
*
* _Available since v4.7._
*/
function toInt200(int256 value) internal pure returns (int200 downcasted) {
downcasted = int200(value);
require(downcasted == value, "SafeCast: value doesn't fit in 200 bits");
}
/**
* @dev Returns the downcasted int192 from int256, reverting on
* overflow (when the input is less than smallest int192 or
* greater than largest int192).
*
* Counterpart to Solidity's `int192` operator.
*
* Requirements:
*
* - input must fit into 192 bits
*
* _Available since v4.7._
*/
function toInt192(int256 value) internal pure returns (int192 downcasted) {
downcasted = int192(value);
require(downcasted == value, "SafeCast: value doesn't fit in 192 bits");
}
/**
* @dev Returns the downcasted int184 from int256, reverting on
* overflow (when the input is less than smallest int184 or
* greater than largest int184).
*
* Counterpart to Solidity's `int184` operator.
*
* Requirements:
*
* - input must fit into 184 bits
*
* _Available since v4.7._
*/
function toInt184(int256 value) internal pure returns (int184 downcasted) {
downcasted = int184(value);
require(downcasted == value, "SafeCast: value doesn't fit in 184 bits");
}
/**
* @dev Returns the downcasted int176 from int256, reverting on
* overflow (when the input is less than smallest int176 or
* greater than largest int176).
*
* Counterpart to Solidity's `int176` operator.
*
* Requirements:
*
* - input must fit into 176 bits
*
* _Available since v4.7._
*/
function toInt176(int256 value) internal pure returns (int176 downcasted) {
downcasted = int176(value);
require(downcasted == value, "SafeCast: value doesn't fit in 176 bits");
}
/**
* @dev Returns the downcasted int168 from int256, reverting on
* overflow (when the input is less than smallest int168 or
* greater than largest int168).
*
* Counterpart to Solidity's `int168` operator.
*
* Requirements:
*
* - input must fit into 168 bits
*
* _Available since v4.7._
*/
function toInt168(int256 value) internal pure returns (int168 downcasted) {
downcasted = int168(value);
require(downcasted == value, "SafeCast: value doesn't fit in 168 bits");
}
/**
* @dev Returns the downcasted int160 from int256, reverting on
* overflow (when the input is less than smallest int160 or
* greater than largest int160).
*
* Counterpart to Solidity's `int160` operator.
*
* Requirements:
*
* - input must fit into 160 bits
*
* _Available since v4.7._
*/
function toInt160(int256 value) internal pure returns (int160 downcasted) {
downcasted = int160(value);
require(downcasted == value, "SafeCast: value doesn't fit in 160 bits");
}
/**
* @dev Returns the downcasted int152 from int256, reverting on
* overflow (when the input is less than smallest int152 or
* greater than largest int152).
*
* Counterpart to Solidity's `int152` operator.
*
* Requirements:
*
* - input must fit into 152 bits
*
* _Available since v4.7._
*/
function toInt152(int256 value) internal pure returns (int152 downcasted) {
downcasted = int152(value);
require(downcasted == value, "SafeCast: value doesn't fit in 152 bits");
}
/**
* @dev Returns the downcasted int144 from int256, reverting on
* overflow (when the input is less than smallest int144 or
* greater than largest int144).
*
* Counterpart to Solidity's `int144` operator.
*
* Requirements:
*
* - input must fit into 144 bits
*
* _Available since v4.7._
*/
function toInt144(int256 value) internal pure returns (int144 downcasted) {
downcasted = int144(value);
require(downcasted == value, "SafeCast: value doesn't fit in 144 bits");
}
/**
* @dev Returns the downcasted int136 from int256, reverting on
* overflow (when the input is less than smallest int136 or
* greater than largest int136).
*
* Counterpart to Solidity's `int136` operator.
*
* Requirements:
*
* - input must fit into 136 bits
*
* _Available since v4.7._
*/
function toInt136(int256 value) internal pure returns (int136 downcasted) {
downcasted = int136(value);
require(downcasted == value, "SafeCast: value doesn't fit in 136 bits");
}
/**
* @dev Returns the downcasted int128 from int256, reverting on
* overflow (when the input is less than smallest int128 or
* greater than largest int128).
*
* Counterpart to Solidity's `int128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*
* _Available since v3.1._
*/
function toInt128(int256 value) internal pure returns (int128 downcasted) {
downcasted = int128(value);
require(downcasted == value, "SafeCast: value doesn't fit in 128 bits");
}
/**
* @dev Returns the downcasted int120 from int256, reverting on
* overflow (when the input is less than smallest int120 or
* greater than largest int120).
*
* Counterpart to Solidity's `int120` operator.
*
* Requirements:
*
* - input must fit into 120 bits
*
* _Available since v4.7._
*/
function toInt120(int256 value) internal pure returns (int120 downcasted) {
downcasted = int120(value);
require(downcasted == value, "SafeCast: value doesn't fit in 120 bits");
}
/**
* @dev Returns the downcasted int112 from int256, reverting on
* overflow (when the input is less than smallest int112 or
* greater than largest int112).
*
* Counterpart to Solidity's `int112` operator.
*
* Requirements:
*
* - input must fit into 112 bits
*
* _Available since v4.7._
*/
function toInt112(int256 value) internal pure returns (int112 downcasted) {
downcasted = int112(value);
require(downcasted == value, "SafeCast: value doesn't fit in 112 bits");
}
/**
* @dev Returns the downcasted int104 from int256, reverting on
* overflow (when the input is less than smallest int104 or
* greater than largest int104).
*
* Counterpart to Solidity's `int104` operator.
*
* Requirements:
*
* - input must fit into 104 bits
*
* _Available since v4.7._
*/
function toInt104(int256 value) internal pure returns (int104 downcasted) {
downcasted = int104(value);
require(downcasted == value, "SafeCast: value doesn't fit in 104 bits");
}
/**
* @dev Returns the downcasted int96 from int256, reverting on
* overflow (when the input is less than smallest int96 or
* greater than largest int96).
*
* Counterpart to Solidity's `int96` operator.
*
* Requirements:
*
* - input must fit into 96 bits
*
* _Available since v4.7._
*/
function toInt96(int256 value) internal pure returns (int96 downcasted) {
downcasted = int96(value);
require(downcasted == value, "SafeCast: value doesn't fit in 96 bits");
}
/**
* @dev Returns the downcasted int88 from int256, reverting on
* overflow (when the input is less than smallest int88 or
* greater than largest int88).
*
* Counterpart to Solidity's `int88` operator.
*
* Requirements:
*
* - input must fit into 88 bits
*
* _Available since v4.7._
*/
function toInt88(int256 value) internal pure returns (int88 downcasted) {
downcasted = int88(value);
require(downcasted == value, "SafeCast: value doesn't fit in 88 bits");
}
/**
* @dev Returns the downcasted int80 from int256, reverting on
* overflow (when the input is less than smallest int80 or
* greater than largest int80).
*
* Counterpart to Solidity's `int80` operator.
*
* Requirements:
*
* - input must fit into 80 bits
*
* _Available since v4.7._
*/
function toInt80(int256 value) internal pure returns (int80 downcasted) {
downcasted = int80(value);
require(downcasted == value, "SafeCast: value doesn't fit in 80 bits");
}
/**
* @dev Returns the downcasted int72 from int256, reverting on
* overflow (when the input is less than smallest int72 or
* greater than largest int72).
*
* Counterpart to Solidity's `int72` operator.
*
* Requirements:
*
* - input must fit into 72 bits
*
* _Available since v4.7._
*/
function toInt72(int256 value) internal pure returns (int72 downcasted) {
downcasted = int72(value);
require(downcasted == value, "SafeCast: value doesn't fit in 72 bits");
}
/**
* @dev Returns the downcasted int64 from int256, reverting on
* overflow (when the input is less than smallest int64 or
* greater than largest int64).
*
* Counterpart to Solidity's `int64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*
* _Available since v3.1._
*/
function toInt64(int256 value) internal pure returns (int64 downcasted) {
downcasted = int64(value);
require(downcasted == value, "SafeCast: value doesn't fit in 64 bits");
}
/**
* @dev Returns the downcasted int56 from int256, reverting on
* overflow (when the input is less than smallest int56 or
* greater than largest int56).
*
* Counterpart to Solidity's `int56` operator.
*
* Requirements:
*
* - input must fit into 56 bits
*
* _Available since v4.7._
*/
function toInt56(int256 value) internal pure returns (int56 downcasted) {
downcasted = int56(value);
require(downcasted == value, "SafeCast: value doesn't fit in 56 bits");
}
/**
* @dev Returns the downcasted int48 from int256, reverting on
* overflow (when the input is less than smallest int48 or
* greater than largest int48).
*
* Counterpart to Solidity's `int48` operator.
*
* Requirements:
*
* - input must fit into 48 bits
*
* _Available since v4.7._
*/
function toInt48(int256 value) internal pure returns (int48 downcasted) {
downcasted = int48(value);
require(downcasted == value, "SafeCast: value doesn't fit in 48 bits");
}
/**
* @dev Returns the downcasted int40 from int256, reverting on
* overflow (when the input is less than smallest int40 or
* greater than largest int40).
*
* Counterpart to Solidity's `int40` operator.
*
* Requirements:
*
* - input must fit into 40 bits
*
* _Available since v4.7._
*/
function toInt40(int256 value) internal pure returns (int40 downcasted) {
downcasted = int40(value);
require(downcasted == value, "SafeCast: value doesn't fit in 40 bits");
}
/**
* @dev Returns the downcasted int32 from int256, reverting on
* overflow (when the input is less than smallest int32 or
* greater than largest int32).
*
* Counterpart to Solidity's `int32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*
* _Available since v3.1._
*/
function toInt32(int256 value) internal pure returns (int32 downcasted) {
downcasted = int32(value);
require(downcasted == value, "SafeCast: value doesn't fit in 32 bits");
}
/**
* @dev Returns the downcasted int24 from int256, reverting on
* overflow (when the input is less than smallest int24 or
* greater than largest int24).
*
* Counterpart to Solidity's `int24` operator.
*
* Requirements:
*
* - input must fit into 24 bits
*
* _Available since v4.7._
*/
function toInt24(int256 value) internal pure returns (int24 downcasted) {
downcasted = int24(value);
require(downcasted == value, "SafeCast: value doesn't fit in 24 bits");
}
/**
* @dev Returns the downcasted int16 from int256, reverting on
* overflow (when the input is less than smallest int16 or
* greater than largest int16).
*
* Counterpart to Solidity's `int16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*
* _Available since v3.1._
*/
function toInt16(int256 value) internal pure returns (int16 downcasted) {
downcasted = int16(value);
require(downcasted == value, "SafeCast: value doesn't fit in 16 bits");
}
/**
* @dev Returns the downcasted int8 from int256, reverting on
* overflow (when the input is less than smallest int8 or
* greater than largest int8).
*
* Counterpart to Solidity's `int8` operator.
*
* Requirements:
*
* - input must fit into 8 bits
*
* _Available since v3.1._
*/
function toInt8(int256 value) internal pure returns (int8 downcasted) {
downcasted = int8(value);
require(downcasted == value, "SafeCast: value doesn't fit in 8 bits");
}
/**
* @dev Converts an unsigned uint256 into a signed int256.
*
* Requirements:
*
* - input must be less than or equal to maxInt256.
*
* _Available since v3.0._
*/
function toInt256(uint256 value) internal pure returns (int256) {
// Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive
require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256");
return int256(value);
}
}/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
pragma solidity >0.5.0 <0.9.0;
pragma abicoder v2;
// SPDX-License-Identifier: GPL-3.0-only
interface RocketNetworkBalancesInterface {
function getBalancesTimestamp() external view returns (uint256);
function getBalancesBlock() external view returns (uint256);
function getTotalETHBalance() external view returns (uint256);
function getStakingETHBalance() external view returns (uint256);
function getTotalRETHSupply() external view returns (uint256);
function getETHUtilizationRate() external view returns (uint256);
function submitBalances(uint256 _block, uint256 _slotTimestamp, uint256 _total, uint256 _staking, uint256 _rethSupply) external;
function executeUpdateBalances(uint256 _block, uint256 _slotTimestamp, uint256 _totalEth, uint256 _stakingEth, uint256 _rethSupply) external;
}/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
pragma solidity >0.5.0 <0.9.0;
// SPDX-License-Identifier: GPL-3.0-only
interface AddressQueueStorageInterface {
function getLength(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 enqueueItem(bytes32 _key, address _value) external;
function dequeueItem(bytes32 _key) external returns (address);
function removeItem(bytes32 _key, address _value) external;
}/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >0.5.0 <0.9.0;
pragma abicoder v2;
interface LinkedListStorageInterface {
struct DepositQueueValue {
address receiver; // the address that will receive the requested value
uint32 validatorId; // internal validator id
uint32 suppliedValue; // in milliether
uint32 requestedValue; // in milliether
}
struct DepositQueueKey {
address receiver; // the address that will receive the requested value
uint32 validatorId; // internal validator id
}
function getLength(bytes32 _namespace) external view returns (uint256);
function getItem(bytes32 _namespace, uint256 _index) external view returns (DepositQueueValue memory);
function peekItem(bytes32 _namespace) external view returns (DepositQueueValue memory);
function getIndexOf(bytes32 _namespace, DepositQueueKey memory _key) external view returns (uint256);
function getHeadIndex(bytes32 _namespace) external view returns (uint256);
function enqueueItem(bytes32 _namespace, DepositQueueValue memory _value) external;
function dequeueItem(bytes32 _namespace) external returns (DepositQueueValue memory);
function removeItem(bytes32 _namespace, DepositQueueKey memory _key) external;
function scan(bytes32 _namespace, uint256 _startIndex, uint256 _count) external view returns (DepositQueueValue[] memory entries, uint256 nextIndex);
}/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >0.5.0 <0.9.0;
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 |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
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 sender that isn't a registered megapool
*/
modifier onlyRegisteredMegapool(address _megapoolAddress) {
require(getBool(keccak256(abi.encodePacked("megapool.exists", _megapoolAddress))), "Invalid megapool");
_;
}
/**
* @dev Throws if called by any sender that isn't a registered minipool or megapool
*/
modifier onlyRegisteredMinipoolOrMegapool(address _caller) {
require(
getBool(keccak256(abi.encodePacked("megapool.exists", _caller))) ||
getBool(keccak256(abi.encodePacked("minipool.exists", _caller)))
, "Invalid caller");
_;
}
/**
* @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 |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
pragma solidity >0.5.0 <0.9.0;
// SPDX-License-Identifier: GPL-3.0-only
interface RocketDAOProtocolSettingsDepositInterface {
function getDepositEnabled() external view returns (bool);
function getAssignDepositsEnabled() external view returns (bool);
function getMinimumDeposit() external view returns (uint256);
function getMaximumDepositPoolSize() external view returns (uint256);
function getMaximumDepositAssignments() external view returns (uint256);
function getMaximumDepositSocialisedAssignments() external view returns (uint256);
function getDepositFee() external view returns (uint256);
function getExpressQueueRate() external view returns (uint256);
function getExpressQueueTicketsBaseProvision() external view returns (uint256);
}/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
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 |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
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);
function getMaximumPenaltyCount() external view returns (uint256);
}/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
pragma solidity >0.5.0 <0.9.0;
// SPDX-License-Identifier: GPL-3.0-only
interface RocketDAOProtocolSettingsNetworkInterface {
function getNodeConsensusThreshold() external view returns (uint256);
function getNodePenaltyThreshold() external view returns (uint256);
function getPerPenaltyRate() external view returns (uint256);
function getSubmitBalancesEnabled() external view returns (bool);
function getSubmitBalancesFrequency() external view returns (uint256);
function getSubmitPricesEnabled() external view returns (bool);
function getSubmitPricesFrequency() external view returns (uint256);
function getMinimumNodeFee() external view returns (uint256);
function getTargetNodeFee() external view returns (uint256);
function getMaximumNodeFee() external view returns (uint256);
function getNodeFeeDemandRange() external view returns (uint256);
function getTargetRethCollateralRate() external view returns (uint256);
function getRethDepositDelay() external view returns (uint256);
function getSubmitRewardsEnabled() external view returns (bool);
function getMaxNodeShareSecurityCouncilAdder() external view returns (uint256);
function getVoterShare() external view returns (uint256);
function getProtocolDAOShare() external view returns (uint256);
function getNodeShare() external view returns (uint256);
function getNodeShareSecurityCouncilAdder() external view returns (uint256);
function getRethCommission() external view returns (uint256);
function getEffectiveVoterShare() external view returns (uint256);
function getEffectiveNodeShare() external view returns (uint256);
function getAllowListedControllers() external view returns (address[] memory);
function getMaxRethDelta() external view returns (uint256);
function isAllowListedController(address _address) external view returns (bool);
function setNodeShareSecurityCouncilAdder(uint256 _value) external;
function setNodeCommissionShare(uint256 _value) external;
function setVoterShare(uint256 _value) external;
function setProtocolDAOShare(uint256 _value) external;
}/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
pragma solidity >0.5.0 <0.9.0;
// SPDX-License-Identifier: GPL-3.0-only
interface RocketDepositPoolInterface {
function getBalance() external view returns (uint256);
function getNodeBalance() external view returns (uint256);
function getUserBalance() external view returns (int256);
function getNodeCreditBalance(address _nodeAddress) external view returns (uint256);
function getExcessBalance() external view returns (uint256);
function deposit() external payable;
function getMaximumDepositAmount() external view returns (uint256);
function nodeDeposit(uint256 _totalAmount) external payable;
function recycleDissolvedDeposit() external payable;
function recycleExcessCollateral() external payable;
function recycleLiquidatedStake() external payable;
function maybeAssignDeposits(uint256 _max) external;
function assignDeposits(uint256 _max) external;
function withdrawExcessBalance(uint256 _amount) external;
function requestFunds(uint256 _bondAmount, uint32 _validatorId, uint256 _amount, bool _useExpressTicket) external;
function exitQueue(address _nodeAddress, uint32 _validatorId, bool _expressQueue) external;
function applyCredit(address _nodeAddress, uint256 _amount) external;
function reduceBond(address _nodeAddress, uint256 _amount) external;
function fundsReturned(address _nodeAddress, uint256 _nodeAmount, uint256 _userAmount) external;
function withdrawCredit(uint256 _amount) external;
function withdrawCreditFor(address _nodeAddress, uint256 _amount) external;
function getQueueTop() external view returns (address receiver, bool assignmentPossible, uint256 headMovedBlock);
function getQueueIndex() external view returns (uint256);
function getMinipoolQueueLength() external view returns (uint256);
function getExpressQueueLength() external view returns (uint256);
function getStandardQueueLength() external view returns (uint256);
function getTotalQueueLength() external view returns (uint256);
}/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >0.5.0 <0.9.0;
struct Withdrawal {
uint64 index;
uint64 validatorIndex;
bytes20 withdrawalCredentials;
uint64 amountInGwei;
}
struct WithdrawalProof {
uint64 withdrawalSlot;
uint16 withdrawalNum;
Withdrawal withdrawal;
bytes32[] witnesses;
}
struct Validator {
bytes pubkey;
bytes32 withdrawalCredentials;
uint64 effectiveBalance;
bool slashed;
uint64 activationEligibilityEpoch;
uint64 activationEpoch;
uint64 exitEpoch;
uint64 withdrawableEpoch;
}
struct ValidatorProof {
uint40 validatorIndex;
Validator validator;
bytes32[] witnesses;
}
struct SlotProof {
uint64 slot;
bytes32[] witnesses;
}
interface BeaconStateVerifierInterface {
function verifyValidator(uint64 _slotTimestamp, uint64 _slot, ValidatorProof calldata _proof) external view returns (bool);
function verifyWithdrawal(uint64 _slotTimestamp, uint64 _slot, WithdrawalProof calldata _proof) external view returns (bool);
function verifySlot(uint64 _slotTimestamp, SlotProof calldata _proof) external view returns (bool);
}/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >0.5.0 <0.9.0;
import "../../interface/RocketStorageInterface.sol";
interface RocketMegapoolDelegateBaseInterface {
function deprecate() external;
function getExpirationTime() external view returns (uint256);
}/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity 0.8.30;
import {RocketStorageInterface} from "../../interface/RocketStorageInterface.sol";
// ******************************************************
// Note: This contract MUST only be appended to. All
// deployed megapool contracts must maintain a
// consistent storage layout with RocketMegapoolDelegate.
// ******************************************************
/// @dev The RocketMegapool contract storage layout, shared by RocketMegapoolDelegate and RocketMegapoolBase
abstract contract RocketMegapoolStorageLayout {
// Status of individual validators
enum Status {
InQueue,
PreStaked,
Staking,
Exited,
Dissolved
}
// Information about individual validators
struct ValidatorInfo {
uint32 lastAssignmentTime; // Timestamp of when the last fund assignment took place
uint32 lastRequestedValue; // Value in milliether last requested
uint32 lastRequestedBond; // Value in milliether of the bond supplied for last request for funds
uint32 depositValue; // Total amount deposited to beaconchain in gwei
bool staked; // Whether the validator has staked the minimum required to begin validating (32 ETH)
bool exited; // Whether the validator has exited the beacon chain
bool inQueue; // Whether the validator is currently awaiting funds from the deposit pool
bool inPrestake; // Whether the validator is currently awaiting the stake operation
bool expressUsed; // Whether the last request for funds consumed an express ticket
bool dissolved; // Whether the validator failed to prestake their initial deposit in time
bool exiting; // Whether the validator is queued to exit on the beaconchain
bool locked; // Whether the validator has been locked by the oDAO for not exiting
uint64 exitBalance; // Final balance of the validator at withdrawable_epoch in gwei (amount returned to EL)
uint64 lockedTime; // The slot this validator was challenged about its exit status
}
//
// Delegate state
//
bool internal storageState; // Used to prevent direct calls to the delegate contract
uint256 internal expirationTime; // Used to store the expiry timestamp of this delegate (0 meaning not expiring)
//
// Proxy state
//
address internal rocketMegapoolDelegate; // The current delegate contract address
bool internal useLatestDelegate; // Whether this proxy always uses the latest delegate
//
// Megapool state
//
address internal nodeAddress; // Megapool owner
uint32 internal numValidators; // Number of individual validators handled by this megapool
uint32 internal numInactiveValidators; // Number of validators that are no longer contributing to bond requirement
uint256 internal assignedValue; // ETH assigned from DP pending prestake/stake
uint256 internal refundValue; // ETH refunded to the owner after a dissolution
uint256 internal nodeBond; // Value of node ETH bond (including value yet to be assigned/deposited)
uint256 internal userCapital; // Value of user supplied capital (including value yet to be assigned/deposited)
uint256 internal nodeQueuedBond; // Value of node ETH bond (yet to be assigned/deposited to beacon chain)
uint256 internal userQueuedCapital; // Value of user supplied capital (yet to be assigned/deposited to beacon chain)
uint256 internal debt; // Amount the owner owes the DP
uint256 internal lastDistributionTime; // The block of the last time a distribution of rewards was executed
mapping(uint32 => ValidatorInfo) internal validators;
mapping(uint32 => bytes) internal prestakeSignatures;
mapping(uint32 => bytes) internal pubkeys;
uint32 internal numLockedValidators; // Number of validators currently locked
uint32 internal numExitingValidators; // Number of validators currently exiting
uint256 internal __version1Boundary; // Unused full slot width boundary
}/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >0.5.0 <0.9.0;
import "../util/BeaconStateVerifierInterface.sol";
import {RocketMegapoolDelegateBaseInterface} from "./RocketMegapoolDelegateBaseInterface.sol";
import {RocketMegapoolStorageLayout} from "../../contract/megapool/RocketMegapoolStorageLayout.sol";
interface RocketMegapoolDelegateInterface is RocketMegapoolDelegateBaseInterface {
struct StateProof {
bytes data;
}
function newValidator(uint256 _bondAmount, bool _useExpressTicket, bytes calldata _validatorPubkey, bytes calldata _validatorSignature, bytes32 _depositDataRoot) external;
function dequeue(uint32 _validatorId) external;
function reduceBond(uint256 _amount) external;
function assignFunds(uint32 _validatorId) external payable;
function stake(uint32 _validatorId) external;
function dissolveValidator(uint32 _validatorId) external;
function getNodeAddress() external returns (address);
function distribute() external;
function claim() external;
function repayDebt() external payable;
function challengeExit(uint32 _validatorId) external;
function notifyNotExit(uint32 _validatorId, uint64 _slotTimestamp) external;
function notifyExit(uint32 _validatorId, uint64 _withdrawableEpoch, uint64 _recentEpoch) external;
function notifyFinalBalance(uint32 _validatorId, uint64 _amountInGwei, address _caller, uint64 _withdrawalEpoch, uint64 _recentEpoch) external;
function applyPenalty(uint256 _amount) external;
function getValidatorCount() external view returns (uint32);
function getActiveValidatorCount() external view returns (uint32);
function getExitingValidatorCount() external view returns (uint32);
function getLockedValidatorCount() external view returns (uint32);
function getValidatorInfo(uint32 _validatorId) external view returns (RocketMegapoolStorageLayout.ValidatorInfo memory);
function getValidatorPubkey(uint32 _validatorId) external view returns (bytes memory);
function getValidatorInfoAndPubkey(uint32 _validatorId) external view returns (RocketMegapoolStorageLayout.ValidatorInfo memory info, bytes memory pubkey);
function getAssignedValue() external view returns (uint256);
function getDebt() external view returns (uint256);
function getRefundValue() external view returns (uint256);
function getNodeBond() external view returns (uint256);
function getUserCapital() external view returns (uint256);
function getNodeQueuedBond() external view returns (uint256);
function getUserQueuedCapital() external view returns (uint256);
function calculatePendingRewards() external view returns (uint256 nodeRewards, uint256 voterRewards, uint256 protocolDAORewards, uint256 rethRewards);
function calculateRewards(uint256 _amount) external view returns (uint256 nodeRewards, uint256 voterRewards, uint256 protocolDAORewards, uint256 rethRewards);
function getPendingRewards() external view returns (uint256);
function getLastDistributionTime() external view returns (uint256);
function getNewValidatorBondRequirement() external view returns (uint256);
function getWithdrawalCredentials() external view returns (bytes32);
}/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >0.5.0 <0.9.0;
import "../../interface/RocketStorageInterface.sol";
interface RocketMegapoolProxyInterface {
function initialise(address _nodeAddress) external;
function delegateUpgrade() external;
function setUseLatestDelegate(bool _state) external;
function getUseLatestDelegate() external view returns (bool);
function getDelegate() external view returns (address);
function getEffectiveDelegate() external view returns (address);
function getDelegateExpired() external view returns (bool);
}/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >0.5.0 <0.9.0;
import {RocketMegapoolDelegateInterface} from "./RocketMegapoolDelegateInterface.sol";
import {RocketMegapoolProxyInterface} from "./RocketMegapoolProxyInterface.sol";
interface RocketMegapoolInterface is RocketMegapoolDelegateInterface, RocketMegapoolProxyInterface {
}/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
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 |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
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 |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
pragma solidity >0.5.0 <0.9.0;
// SPDX-License-Identifier: GPL-3.0-only
import "../../types/MinipoolDeposit.sol";
interface RocketMinipoolQueueInterface {
function getTotalLength() external view returns (uint256);
function getContainsLegacy() external view returns (bool);
function getLengthLegacy(MinipoolDeposit _depositType) external view returns (uint256);
function getLength() external view returns (uint256);
function getTotalCapacity() external view returns (uint256);
function getEffectiveCapacity() external view returns (uint256);
function getNextCapacityLegacy() external view returns (uint256);
function getNextDepositLegacy() external view returns (MinipoolDeposit, uint256);
function enqueueMinipool(address _minipool) external;
function dequeueMinipoolByDepositLegacy(MinipoolDeposit _depositType) external returns (address minipoolAddress);
function dequeueMinipools(uint256 _maxToDequeue) external returns (address[] memory minipoolAddress);
function removeMinipool(MinipoolDeposit _depositType) external;
function getMinipoolAt(uint256 _index) external view returns(address);
function getMinipoolPosition(address _minipool) external view returns (int256);
}/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >0.5.0 <0.9.0;
/// @notice Accounting for snapshotting of values based on block numbers
interface RocketNetworkSnapshotsInterface {
struct Checkpoint224 {
uint32 _block;
uint224 _value;
}
function push(bytes32 _key, uint224 _value) external;
function length(bytes32 _key) external view returns (uint256);
function latest(bytes32 _key) external view returns (bool exists, uint32 block, uint224 value);
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 lookupCheckpoint(bytes32 _key, uint32 _block) external view returns (bool exists, uint32 block, uint224 value);
function lookupRecent(bytes32 _key, uint32 _block, uint256 _recency) external view returns (uint224);
}/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
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 |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
// 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 getNodeAddresses(uint256 _offset, uint256 _limit) external view returns (address[] memory);
function deployMegapool() external returns (address);
function getExpressTicketCount(address _nodeAddress) external view returns (uint256);
function useExpressTicket(address _nodeAddress) external;
function provisionExpressTickets(address _nodeAddress) external;
function getExpressTicketsProvisioned(address _nodeAddress) external view returns (bool);
function refundExpressTicket(address _nodeAddress) external;
function getMegapoolAddress(address _nodeAddress) external view returns (address);
function getUnclaimedRewards(address _nodeAddress) external view returns (uint256);
function addUnclaimedRewards(address _nodeAddress) external payable;
function claimUnclaimedRewards(address _nodeAddress) external;
}/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
// 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 |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
pragma solidity >0.5.0 <0.9.0;
// SPDX-License-Identifier: GPL-3.0-only
import "../util/IERC20.sol";
interface RocketTokenRETHInterface is IERC20 {
function getEthValue(uint256 _rethAmount) external view returns (uint256);
function getRethValue(uint256 _ethAmount) external view returns (uint256);
function getExchangeRate() external view returns (uint256);
function getTotalCollateral() external view returns (uint256);
function getCollateralRate() external view returns (uint256);
function depositExcess() external payable;
function depositExcessCollateral() external;
function mint(uint256 _ethAmount, address _to) external;
function burn(uint256 _rethAmount) external;
}/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)
import "./IERC20.sol";
pragma solidity >0.5.0 <0.9.0;
interface IERC20Burnable is IERC20 {
function burn(uint256 amount) external;
function burnFrom(address account, uint256 amount) external;
}/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
pragma solidity >0.5.0 <0.9.0;
// SPDX-License-Identifier: GPL-3.0-only
import "./util/IERC20Burnable.sol";
interface RocketVaultInterface {
function balanceOf(string memory _networkContractName) external view returns (uint256);
function depositEther() external payable;
function withdrawEther(uint256 _amount) external;
function depositToken(string memory _networkContractName, IERC20 _tokenAddress, uint256 _amount) external;
function withdrawToken(address _withdrawalAddress, IERC20 _tokenAddress, uint256 _amount) external;
function balanceOfToken(string memory _networkContractName, IERC20 _tokenAddress) external view returns (uint256);
function transferToken(string memory _networkContractName, IERC20 _tokenAddress, uint256 _amount) external;
function burnToken(IERC20Burnable _tokenAddress, uint256 _amount) external;
}/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
pragma solidity >0.5.0 <0.9.0;
// SPDX-License-Identifier: GPL-3.0-only
interface RocketVaultWithdrawerInterface {
function receiveVaultWithdrawalETH() external payable;
}/**
* .
* / \
* |.'.|
* |'.'|
* ,'| |'.
* |,-'-|-'-.|
* __|_| | _ _ _____ _
* | ___ \| | | | | | ___ \ | |
* | |_/ /|__ ___| | _____| |_ | |_/ /__ ___ | |
* | // _ \ / __| |/ / _ \ __| | __/ _ \ / _ \| |
* | |\ \ (_) | (__| < __/ |_ | | | (_) | (_) | |
* \_| \_\___/ \___|_|\_\___|\__| \_| \___/ \___/|_|
* +---------------------------------------------------+
* | DECENTRALISED STAKING PROTOCOL FOR ETHEREUM |
* +---------------------------------------------------+
*
* Rocket Pool is a first-of-its-kind Ethereum staking pool protocol, designed to
* be community-owned, decentralised, permissionless, & trustless.
*
* For more information about Rocket Pool, visit https://rocketpool.net
*
* Authored by the Rocket Pool Core Team
* Contributors: https://github.com/rocket-pool/rocketpool/graphs/contributors
* A special thanks to the Rocket Pool community for all their contributions.
*
*/
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity >0.5.0 <0.9.0;
interface RocketMegapoolFactoryInterface {
function initialise() external;
function getExpectedAddress(address _nodeAddress) external view returns (address);
function getMegapoolDeployed(address _nodeAddress) external view returns (bool);
function deployContract(address _nodeAddress) external returns (address);
function getOrDeployContract(address _nodeAddress) external returns (address);
function upgradeDelegate(address _newDelegateAddress) external;
function getDelegateExpiry(address _delegateAddress) external view returns (uint256);
}{
"viaIR": true,
"optimizer": {
"enabled": true,
"runs": 15000
},
"evmVersion": "paris",
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"contract RocketStorageInterface","name":"_rocketStorageAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"nodeAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"CreditWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"minipool","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"DepositAssigned","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"DepositReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"DepositRecycled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"ExcessWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"FundsAssigned","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"validatorId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bool","name":"expressQueue","type":"bool"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"FundsRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"nodeAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"QueueExited","type":"event"},{"inputs":[{"internalType":"address","name":"_nodeAddress","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"applyCredit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_max","type":"uint256"}],"name":"assignDeposits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_nodeAddress","type":"address"},{"internalType":"uint32","name":"_validatorId","type":"uint32"},{"internalType":"bool","name":"_expressQueue","type":"bool"}],"name":"exitQueue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_nodeAddress","type":"address"},{"internalType":"uint256","name":"_nodeAmount","type":"uint256"},{"internalType":"uint256","name":"_userAmount","type":"uint256"}],"name":"fundsReturned","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getExcessBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getExpressQueueLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMaximumDepositAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMinipoolQueueLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNodeBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_nodeAddress","type":"address"}],"name":"getNodeCreditBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getQueueIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getQueueTop","outputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"bool","name":"assignmentPossible","type":"bool"},{"internalType":"uint256","name":"headMovedBlock","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStandardQueueLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalQueueLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getUserBalance","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_max","type":"uint256"}],"name":"maybeAssignDeposits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_bondAmount","type":"uint256"}],"name":"nodeDeposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"receiveVaultWithdrawalETH","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"recycleDissolvedDeposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"recycleExcessCollateral","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"recycleLiquidatedStake","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_nodeAddress","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"reduceBond","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_bondAmount","type":"uint256"},{"internalType":"uint32","name":"_validatorId","type":"uint32"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bool","name":"_expressQueue","type":"bool"}],"name":"requestFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawCredit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_nodeAddress","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawCreditFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawExcessBalance","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60c08060405234610145576020816159a0803803809161001f828561014a565b83398101031261014557516001600160a01b038116810361014557600080546001600160a81b03191660089290921b610100600160a81b03169190911760041790556040805190610070908261014a565b600b81526a1c9bd8dad95d15985d5b1d60aa1b60208201526001600160a01b039061009a90610183565b166080526040516100ac60408261014a565b600f81526e0e4dec6d6cae8a8ded6cadca48aa89608b1b60208201526001600160a01b03906100da90610183565b1660a0526040516156d490816102cc8239608051818181611d4e0152818161221c015281816125aa015281816130c5015281816143ad0152818161467c0152614ac7015260a05181818161054401528181611dc2015281816140d30152818161442e01526151910152f35b600080fd5b601f909101601f19168101906001600160401b0382119082101761016d57604052565b634e487b7160e01b600052604160045260246000fd5b60405160208101916f636f6e74726163742e6164647265737360801b83528181519160005b8381106102b3575050806101cf92603092016000838201520301601f19810183528261014a565b5190206000546040516321f8a72160e01b815260048101929092526020908290602490829060081c6001600160a01b03165afa9081156102a75760009161025e575b506001600160a01b038116156102245790565b60405162461bcd60e51b815260206004820152601260248201527110dbdb9d1c9858dd081b9bdd08199bdd5b9960721b6044820152606490fd5b6020813d60201161029f575b816102776020938361014a565b8101031261029b5751906001600160a01b0382168203610298575038610211565b80fd5b5080fd5b3d915061026a565b6040513d6000823e3d90fd5b602082820181015160308784010152859350016101a856fe6080604052600436101561001257600080fd5b6000803560e01c806312065fe0146124785780631666f5e21461237c5780631b7dd4c0146122db5780631e35fed8146122c05780631eddb626146122a557806322b1751d146120d4578063258260951461205d57806327afc6f5146120425780633350677b1461202757806342e6dfa214611ff657806354fd4d5014611fd657806360be2e1c14611ef057806363a5db9e14611cf157806372f5158d14611ba8578063791d25b114611b8d5780637aab9e1614611af25780637d9d607414611612578063888b042f146115f75780639a8dd16f14610d915780639e2c0c1914610d6e578063a559a64514610bc6578063a673c8e114610b96578063a9a9482214610a73578063b7013dc114610a02578063c095415d14610961578063c6f20e6d14610928578063d0e30db0146103b4578063db82047b146102c95763ef6f886a1461015c57600080fd5b346102c65760206003193601126102c6576101fe6101f960405160208101906101f1816101c533856bffffffffffffffffffffffff19601f927f6e6f64652e657869737473000000000000000000000000000000000000000000835260601b16600b8201520190565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101835282612507565b5190206138dc565b612d27565b6102196001600160a01b036102116133ad565b163014612621565b602460206001600160a01b03835460081c16604051928380927f5b49ff620000000000000000000000000000000000000000000000000000000082523360048301525afa80156102bb57829061027c575b61027991506004359033613e44565b80f35b506020813d6020116102b3575b8161029660209383612507565b810103126102af576102aa61027991612b19565b61026a565b5080fd5b3d9150610289565b6040513d84823e3d90fd5b80fd5b50806003193601126102c6576102e86001600160a01b036102116133ad565b61037a6001600160a01b03610372604051610304604082612507565b600f81527f726f636b6574546f6b656e524554480000000000000000000000000000000000602082015260405161036a816101c560208201947f636f6e74726163742e6164647265737300000000000000000000000000000000865260308301906126cf565b519020613458565b163314612621565b6040513481524260208201527f3a6614e80d02b57255cbb1f8305fbeca53d7e05a4b779d40627919660851292560403392a261027961436d565b50806003193601126102c6576103d36001600160a01b036102116133ad565b6001600160a01b0361041b6040516103ec604082612507565b602081527f726f636b657444414f50726f746f636f6c53657474696e67734465706f73697460208201526134af565b166040517f6ada7847000000000000000000000000000000000000000000000000000000008152602081600481855afa80156108fe57610462918491610909575b5061333c565b6040517f035cf142000000000000000000000000000000000000000000000000000000008152602081600481855afa9081156108fe5783916108cc575b503410610862578190346104b1612548565b016040517ffd6ce89e000000000000000000000000000000000000000000000000000000008152602081600481865afa908115610857578491610822575b50808211610653575b50506020600491604051928380927f0de705b50000000000000000000000000000000000000000000000000000000082525afa9081156102bb578291610619575b506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016803b15610615576040517f94bf804d000000000000000000000000000000000000000000000000000000008152670de0b6b3a76400003493840204909203600483015233602483015282908290604490829084905af180156102bb57610600575b506040513481524260208201527f7aa1a8eb998c779420645fc14513bf058edb347d95c2fc2e6845bdc22f88863160403392a261027961436d565b8161060a91612507565b6102c65780386105c5565b5050fd5b9150506020813d60201161064b575b8161063560209383612507565b810103126106465781905138610539565b600080fd5b3d9150610628565b909192506040517f47fa434a000000000000000000000000000000000000000000000000000000008152602081600481875afa9081156107e85785916107f3575b50156107475760049060206001600160a01b036106e66040516106b8604082612507565b601381527f726f636b65744d696e69706f6f6c517565756500000000000000000000000000848201526134af565b16604051938480927fe60b40bf0000000000000000000000000000000000000000000000000000000082525afa9182156107e85785926107b2575b5061073161073792610731613726565b906126fa565b10610747578190602060046104f8565b60405162461bcd60e51b815260206004820152603f60248201527f546865206465706f73697420706f6f6c2073697a65206166746572206465706f60448201527f736974696e67206578636565647320746865206d6178696d756d2073697a65006064820152608490fd5b91506020823d6020116107e0575b816107cd60209383612507565b8101031261064657905190610731610721565b3d91506107c0565b6040513d87823e3d90fd5b610815915060203d60201161081b575b61080d8183612507565b8101906126b7565b38610694565b503d610803565b9350506020833d60201161084f575b8161083e60209383612507565b8101031261064657839251386104ef565b3d9150610831565b6040513d86823e3d90fd5b608460405162461bcd60e51b815260206004820152603a60248201527f546865206465706f736974656420616d6f756e74206973206c6573732074686160448201527f6e20746865206d696e696d756d206465706f7369742073697a650000000000006064820152fd5b90506020813d6020116108f6575b816108e760209383612507565b8101031261064657513861049f565b3d91506108da565b6040513d85823e3d90fd5b610922915060203d60201161081b5761080d8183612507565b3861045c565b50346102c657806003193601126102c6576060610943612e09565b906001600160a01b0360405193168352151560208301526040820152f35b50806003193601126102c6576109806001600160a01b036102116133ad565b6102796001600160a01b0361037260405161099c604082612507565b600b81527f726f636b65745661756c74000000000000000000000000000000000000000000602082015260405161036a816101c560208201947f636f6e74726163742e6164647265737300000000000000000000000000000000865260308301906126cf565b50346102c657806003193601126102c657610a1b612548565b90610a24613638565b91818382039312818412811691841390151617610a4657602082604051908152f35b807f4e487b7100000000000000000000000000000000000000000000000000000000602492526011600452fd5b50346102c65760606003193601126102c657610279610a90612493565b610aed610ae860405160208101906101f1816101c533856bffffffffffffffffffffffff196023927f6d656761706f6f6c2e6578697374730000000000000000000000000000000000835260601b16600f8201520190565b612ace565b610b006001600160a01b036102116133ad565b610b0c602435826139de565b60405190610b8a82610b5e6020820193846bffffffffffffffffffffffff196034927f6d656761706f6f6c2e6574682e6d6174636865642e6e6f64652e616d6f756e74835260601b1660208201520190565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101845283612507565b60443591519020613cd3565b50346102c65760206003193601126102c657610bbb6001600160a01b036102116133ad565b610279600435612d72565b50346102c65760406003193601126102c6576024610be2612493565b610c3a6101f960405160208101906101f1816101c587856bffffffffffffffffffffffff19601f927f6e6f64652e657869737473000000000000000000000000000000000000000000835260601b16600b8201520190565b610c4d6001600160a01b036102116133ad565b60206001600160a01b03845460081c16604051938480927f5b49ff620000000000000000000000000000000000000000000000000000000082526001600160a01b03861660048301525afa9182156108fe578392610d2e575b506001600160a01b0382163303610cc4576102799160243591613e44565b608460405162461bcd60e51b815260206004820152602660248201527f4d7573742062652063616c6c65642066726f6d207769746864726177616c206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152fd5b9091506020813d602011610d66575b81610d4a60209383612507565b81010312610d6257610d5b90612b19565b9038610ca6565b8280fd5b3d9150610d3d565b50346102c657806003193601126102c6576020610d89612ca5565b604051908152f35b50346102c65760806003193601126102c657600435610dae6124a9565b90604435606435918215159283810361135957610e19610ae860405160208101906101f1816101c533856bffffffffffffffffffffffff196023927f6d656761706f6f6c2e6578697374730000000000000000000000000000000000835260601b16600f8201520190565b610e2c6001600160a01b036102116133ad565b66038d7ea4c6800082066115b35766038d7ea4c68000830661156f57604051907f70dabc9e0000000000000000000000000000000000000000000000000000000082526020826004818a335af19182156113d0578792611533575b50866001600160a01b03610ed1604051610ea2604082612507565b601181527f726f636b65744e6f64654d616e6167657200000000000000000000000000000060208201526134af565b1682156114c557803b156102af578180916024604051809481937fc220f0920000000000000000000000000000000000000000000000000000000083526001600160a01b038a1660048401525af180156102bb576114ac575b50505b610f3681613b7d565b9087610f4a66038d7ea4c680008604613dc6565b92610f5d66038d7ea4c680008804613dc6565b60405190610f6a826124bc565b33825263ffffffff602083019b169a8b815263ffffffff604084019716875263ffffffff60608401921682526001600160a01b03610fde604051610faf604082612507565b601181527f6c696e6b65644c69737453746f7261676500000000000000000000000000000060208201526134af565b1696873b156113595763ffffffff8094926001600160a01b038294604051987fea58ecf5000000000000000000000000000000000000000000000000000000008a5260048a015251166024880152511660448601525116606484015251166084820152818160a48183885af180156102bb57611497575b506001600160a01b03815460081c16803b156102af578180916044604051809481937fadb353dc0000000000000000000000000000000000000000000000000000000083527f43d6a8fcdd5ecf01f71d0e1d9b20163adaa8fbb9e896e8263c967735d0ae5ce060048401528c60248401525af180156102bb5761147e575b50506024916020916000146113db57604051928380927ffd82e9dd0000000000000000000000000000000000000000000000000000000082527f5a55531ca116b9495f14b748a940f79340b078cefcdd2db09ea1ce8b68bad15b60048301525afa80156113d057879061139d575b6001915014611390575b856001600160a01b03611194604051611165604082612507565b601681527f726f636b65744e6574776f726b536e617073686f74730000000000000000000060208201526134af565b16604051602081019061120d816101c587856bffffffffffffffffffffffff196035927f6d656761706f6f6c2e6574682e70726f76696465642e6e6f64652e616d6f756e83527f7400000000000000000000000000000000000000000000000000000000000000602084015260601b1660218201520190565b5190206040517f6838444b000000000000000000000000000000000000000000000000000000008152816004820152602081602481865afa90811561085757867bffffffffffffffffffffffffffffffffffffffffffffffffffffffff809361127e938891611361575b50166126fa565b16823b1561135d576040517f5ba5964900000000000000000000000000000000000000000000000000000000815260048101929092527bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660248201529082908290604490829084905af180156102bb57611344575b50506112ff6113059284612736565b9061394c565b604051928352602083015260408201524260608201527f4040156d881bd2ba289490b90281b228e6c221621274ce90999669f12d74ddfb60803392a280f35b8161134e91612507565b6113595785386112f0565b8580fd5b8380fd5b611383915060203d602011611389575b61137b8183612507565b8101906139aa565b38611277565b503d611371565b611398613d80565b61114b565b506020813d6020116113c8575b816113b760209383612507565b810103126106465760019051611141565b3d91506113aa565b6040513d89823e3d90fd5b604051928380927ffd82e9dd0000000000000000000000000000000000000000000000000000000082527f3676a2bfaf1dbda572dffd9f1bf1596b6bda293af53a4f0eb0ecb236bf64075e60048301525afa80156113d057879061144b575b600191500361114b57611398613d37565b506020813d602011611476575b8161146560209383612507565b81010312610646576001905161143a565b3d9150611458565b8161148891612507565b6114935787386110d3565b8780fd5b816114a191612507565b611493578738611055565b816114b691612507565b6114c1578638610f2a565b8680fd5b803b156102af578180916024604051809481937f4395fb740000000000000000000000000000000000000000000000000000000083526001600160a01b038a1660048401525af180156102bb5761151e575b5050610f2d565b8161152891612507565b6114c1578638611517565b9091506020813d602011611567575b8161154f60209383612507565b810103126114c15761156090612b19565b9038610e87565b3d9150611542565b606460405162461bcd60e51b815260206004820152601860248201527f496e76616c69642072657175657374656420616d6f756e7400000000000000006044820152fd5b606460405162461bcd60e51b815260206004820152601760248201527f496e76616c696420737570706c69656420616d6f756e740000000000000000006044820152fd5b50346102c657806003193601126102c6576020610d89612ba9565b50346102c65760606003193601126102c65761162c612493565b6116346124a9565b60443590811515820361135d57611699610ae860405160208101906101f1816101c533856bffffffffffffffffffffffff196023927f6d656761706f6f6c2e6578697374730000000000000000000000000000000000835260601b16600f8201520190565b6116ac6001600160a01b036102116133ad565b6001600160a01b036116c5604051610faf604082612507565b1691604051916040830183811067ffffffffffffffff821117611ac55760405233835263ffffffff166020830152846116fd82613b7d565b6040517fed8ef8fb0000000000000000000000000000000000000000000000000000000081526004810182905284516001600160a01b0316602482015260208086015163ffffffff1660448301529095919086606481855afa9586156108fe578396611a8e575b50604051957ff3358a3a000000000000000000000000000000000000000000000000000000008752816004880152806024880152608087604481865afa968715610857578497611a5d575b506040517f45134808000000000000000000000000000000000000000000000000000000008152826004820152602081602481875afa9081156107e8578591611a28575b501494823b1561135d576040517f41b93d1b000000000000000000000000000000000000000000000000000000008152600481019290925280516001600160a01b031660248301526020015163ffffffff1660448201529082908290606490829084905af180156102bb57611a0f575b505063ffffffff60608401511666038d7ea4c6800081029080820466038d7ea4c6800014901517156119e25761189890613bc9565b156119cc57836001600160a01b036118b7604051610ea2604082612507565b16803b156102af578180916024604051809481937fa90e35a60000000000000000000000000000000000000000000000000000000083526001600160a01b038b1660048401525af180156102bb576119b7575b505063ffffffff916040916119aa575b01511666038d7ea4c6800081029080820466038d7ea4c68000149015171561197d5761194590613c4e565b7f795bf47f48111f2d01d87912d6b77fa833a62f0c4e2221ae9ecd474ec50d8b3360206001600160a01b03604051934285521692a280f35b6024837f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b6119b2613d80565b61191a565b816119c191612507565b61135d57833861190a565b63ffffffff916040911561191a576119b2613d37565b6024867f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b81611a1991612507565b611a24578438611863565b8480fd5b9450506020843d602011611a55575b81611a4460209383612507565b8101031261064657889351386117f3565b3d9150611a37565b611a8091975060803d608011611a87575b611a788183612507565b810190612b3e565b95386117af565b503d611a6e565b925094506020823d602011611abd575b81611aab60209383612507565b81010312610646578691519438611764565b3d9150611a9e565b6024877f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b50346102c65760406003193601126102c657610279611b0f612493565b60243590611b6b610ae860405160208101906101f1816101c533856bffffffffffffffffffffffff196023927f6d656761706f6f6c2e6578697374730000000000000000000000000000000000835260601b16600f8201520190565b611b7e6001600160a01b036102116133ad565b611b88828261394c565b6139de565b50346102c657806003193601126102c6576020610d896136af565b50806003193601126102c657611bc76001600160a01b036102116133ad565b6040517f6d656761706f6f6c2e6578697374730000000000000000000000000000000000602082019081523360601b6bffffffffffffffffffffffff1916602f830152611c1b916101f181604381016101c5565b8015611ca5575b15611c61576040513481524260208201527f3a6614e80d02b57255cbb1f8305fbeca53d7e05a4b779d40627919660851292560403392a261027961436d565b606460405162461bcd60e51b815260206004820152600e60248201527f496e76616c69642063616c6c65720000000000000000000000000000000000006044820152fd5b50611cec60405160208101907f6d696e69706f6f6c2e657869737473000000000000000000000000000000000082523360601b602f820152602381526101f1604382612507565b611c22565b50346102c65760206003193601126102c657600435611d196001600160a01b036102116133ad565b611d356001600160a01b03610372604051610304604082612507565b611d3d612ba9565b8111611e8657816001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016803b156102af578180916024604051809481937f3bed33ce0000000000000000000000000000000000000000000000000000000083528860048401525af180156102bb57611e71575b506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016803b156102af578183916004604051809481937f6c985a880000000000000000000000000000000000000000000000000000000083525af180156102bb57611e5c575b50506040519081524260208201527f992f462cfb62e164bd03bf07baf2cffce83fbd9370cae10635842b202001212060403392a280f35b81611e6691612507565b6102af578138611e25565b81611e7b91612507565b6102af578138611db7565b608460405162461bcd60e51b815260206004820152602a60248201527f496e73756666696369656e74206578636573732062616c616e636520666f722060448201527f7769746864726177616c000000000000000000000000000000000000000000006064820152fd5b50346102c65760406003193601126102c657610279611f0d612493565b611f65610ae860405160208101906101f1816101c533856bffffffffffffffffffffffff196023927f6d656761706f6f6c2e6578697374730000000000000000000000000000000000835260601b16600f8201520190565b611f786001600160a01b036102116133ad565b60405190611fca82610b5e6020820193846bffffffffffffffffffffffff19602f927f6e6f64652e6465706f7369742e6372656469742e62616c616e63650000000000835260601b16601b8201520190565b6024359151902061386b565b50346102c657806003193601126102c65760ff6020915416604051908152f35b50346102c657806003193601126102c6576020610d8961201f61201761296e565b610731612a1e565b610731612ca5565b50346102c657806003193601126102c6576020610d89612a1e565b50346102c657806003193601126102c6576020610d8961296e565b50346102c65760206003193601126102c6576020610d8961207c612493565b6040516120cc816101c586820194856bffffffffffffffffffffffff19602f927f6e6f64652e6465706f7369742e6372656469742e62616c616e63650000000000835260601b16601b8201520190565b519020613814565b5060206003193601126102c6576120f46001600160a01b036102116133ad565b6121766001600160a01b03610372604051612110604082612507565b601181527f726f636b65744e6f64654465706f736974000000000000000000000000000000602082015260405161036a816101c560208201947f636f6e74726163742e6164647265737300000000000000000000000000000000865260308301906126cf565b34612212575b806001600160a01b03815460081c16803b1561220f578180916044604051809481937fadb353dc0000000000000000000000000000000000000000000000000000000083527f6465706f7369742e706f6f6c2e6e6f64652e62616c616e636500000000000000600484015260043560248401525af180156102bb576121fe5750f35b8161220891612507565b6102c65780f35b50fd5b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001681813b156102c65780600492604051938480927f98ea5fca00000000000000000000000000000000000000000000000000000000825234905af1801561229857612288575b505061217c565b61229191612507565b3881612281565b50604051903d90823e3d90fd5b50346102c657806003193601126102c6576020610d89612743565b50346102c657806003193601126102c6576020610d89613638565b50806003193601126102c6576122fa6001600160a01b036102116133ad565b61037a6001600160a01b03610372604051612316604082612507565b601481527f726f636b657441756374696f6e4d616e61676572000000000000000000000000602082015260405161036a816101c560208201947f636f6e74726163742e6164647265737300000000000000000000000000000000865260308301906126cf565b50346102c65760206003193601126102c6576004356123a46001600160a01b036102116133ad565b6123af81151561266c565b6001600160a01b036123c86040516103ec604082612507565b166040517f47fa434a000000000000000000000000000000000000000000000000000000008152602081600481855afa908115610857578491612459575b50156124155761027991613545565b606460405162461bcd60e51b815260206004820152602060248201527f4465706f7369742061737369676e6d656e7473206172652064697361626c65646044820152fd5b612472915060203d60201161081b5761080d8183612507565b38612406565b50346102c657806003193601126102c6576020610d89612548565b600435906001600160a01b038216820361064657565b6024359063ffffffff8216820361064657565b6080810190811067ffffffffffffffff8211176124d857604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff8211176124d857604052565b6040517f35ee5f87000000000000000000000000000000000000000000000000000000008152602060048201819052601160248301527f726f636b65744465706f736974506f6f6c0000000000000000000000000000006044830152816064817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115612615576000916125e6575090565b90506020813d60201161260d575b8161260160209383612507565b81010312610646575190565b3d91506125f4565b6040513d6000823e3d90fd5b1561262857565b606460405162461bcd60e51b815260206004820152601c60248201527f496e76616c6964206f72206f7574646174656420636f6e7472616374000000006044820152fd5b1561267357565b606460405162461bcd60e51b815260206004820152601660248201527f4d7573742061737369676e206174206c656173742031000000000000000000006044820152fd5b90816020910312610646575180151581036106465790565b9081519160005b8381106126e7575050016000815290565b80602080928401015181850152016126d6565b9190820180921161270757565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b9190820391821161270757565b6001600160a01b0361275c6040516103ec604082612507565b166040517f6ada7847000000000000000000000000000000000000000000000000000000008152602081600481855afa9081156126155760009161294f575b5015612949576127a9612548565b6040517ffd6ce89e000000000000000000000000000000000000000000000000000000008152602081600481865afa90811561261557600091612917575b50600460208294604051928380927f47fa434a0000000000000000000000000000000000000000000000000000000082525afa908115612615576000916128f8575b5061284b575b50818110156128445761284191612736565b90565b5050600090565b909150600460206001600160a01b0361286b6040516106b8604082612507565b16604051928380927fe60b40bf0000000000000000000000000000000000000000000000000000000082525afa908115612615576000916128c4575b506128b5906128bd926126fa565b610731613726565b903861282f565b90506020813d6020116128f0575b816128df60209383612507565b8101031261064657516128bd6128a7565b3d91506128d2565b612911915060203d60201161081b5761080d8183612507565b38612829565b906020823d602011612941575b8161293160209383612507565b810103126102c6575051386127e7565b3d9150612924565b50600090565b612968915060203d60201161081b5761080d8183612507565b3861279b565b602460206001600160a01b036129b960405161298b604082612507565b601381527f61646472657373517565756553746f7261676500000000000000000000000000848201526134af565b16604051928380927ffd82e9dd0000000000000000000000000000000000000000000000000000000082527fa7c30d79bac38383b63cf527b2a68c8a7efff3ba22dfd5b81d98030643ef0fca60048301525afa908115612615576000916125e6575090565b602460206001600160a01b03612a69604051612a3b604082612507565b601181527f6c696e6b65644c69737453746f72616765000000000000000000000000000000848201526134af565b16604051928380927ffd82e9dd0000000000000000000000000000000000000000000000000000000082527f5a55531ca116b9495f14b748a940f79340b078cefcdd2db09ea1ce8b68bad15b60048301525afa908115612615576000916125e6575090565b15612ad557565b606460405162461bcd60e51b815260206004820152601060248201527f496e76616c6964206d656761706f6f6c000000000000000000000000000000006044820152fd5b51906001600160a01b038216820361064657565b519063ffffffff8216820361064657565b9081608091031261064657612b8e606060405192612b5b846124bc565b612b6481612b19565b8452612b7260208201612b2d565b6020850152612b8360408201612b2d565b604085015201612b2d565b606082015290565b8181029291811591840414171561270757565b600460206001600160a01b03612bc66040516106b8604082612507565b16604051928380927fe60b40bf0000000000000000000000000000000000000000000000000000000082525afa801561261557600090612c2e575b612c0e9150610731613726565b612c16612548565b90818110612c25575050600090565b61284191612736565b506020813d602011612c5a575b81612c4860209383612507565b8101031261064657612c0e9051612c01565b3d9150612c3b565b8115612c6c570690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b8115612c6c570490565b602460206001600160a01b03612cc2604051612a3b604082612507565b16604051928380927ffd82e9dd0000000000000000000000000000000000000000000000000000000082527f3676a2bfaf1dbda572dffd9f1bf1596b6bda293af53a4f0eb0ecb236bf64075e60048301525afa908115612615576000916125e6575090565b15612d2e57565b606460405162461bcd60e51b815260206004820152600c60248201527f496e76616c6964206e6f646500000000000000000000000000000000000000006044820152fd5b612d7d81151561266c565b6001600160a01b03612d966040516103ec604082612507565b166040517f47fa434a000000000000000000000000000000000000000000000000000000008152602081600481855afa90811561261557600091612dea575b5015612de657612de491613545565b565b5050565b612e03915060203d60201161081b5761080d8183612507565b38612dd5565b602460206001600160a01b03612e2660405161298b604082612507565b16604051928380927ffd82e9dd0000000000000000000000000000000000000000000000000000000082527fa7c30d79bac38383b63cf527b2a68c8a7efff3ba22dfd5b81d98030643ef0fca60048301525afa9081156126155760009161330a575b506132ff576001600160a01b03612ea6604051610faf604082612507565b166001600160a01b03612ec06040516103ec604082612507565b16916040517ffd82e9dd0000000000000000000000000000000000000000000000000000000081527f5a55531ca116b9495f14b748a940f79340b078cefcdd2db09ea1ce8b68bad15b6004820152602081602481865afa908115612615576000916132cd575b50604051907ffd82e9dd0000000000000000000000000000000000000000000000000000000082527f3676a2bfaf1dbda572dffd9f1bf1596b6bda293af53a4f0eb0ecb236bf64075e6004830152602082602481875afa91821561261557600092613299575b5015908180613291575b61328157612fa26136af565b604051907f1aff58eb0000000000000000000000000000000000000000000000000000000082526020826004818a5afa9182156126155760009261324d575b506001820180831161270757612ff691612c62565b1415809281613245575b5061323c575b81159081613233575b5061322b575b608061302082613b7d565b6024604051809681937f4fd8f05400000000000000000000000000000000000000000000000000000000835260048301525afa9283156126155760009361320a575b506040517f35ee5f87000000000000000000000000000000000000000000000000000000008152602060048201819052601160248301527f726f636b65744465706f736974506f6f6c0000000000000000000000000000006044830152816064817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115612615576000916131d8575b5063ffffffff6060850151169066038d7ea4c6800082029180830466038d7ea4c68000149015171561270757600491602091101595604051928380927f47fa434a0000000000000000000000000000000000000000000000000000000082525afa908115612615576000916131b9575b50156131b0575b6001600160a01b039061318661379d565b90156131a7576fffffffffffffffffffffffffffffffff16925b5116929190565b60801c926131a0565b60009350613175565b6131d2915060203d60201161081b5761080d8183612507565b3861316e565b90506020813d602011613202575b816131f360209383612507565b810103126106465751386130fe565b3d91506131e6565b61322491935060803d608011611a8757611a788183612507565b9138613062565b506001613015565b9050153861300f565b60009150613006565b905038613000565b90916020823d602011613279575b8161326860209383612507565b810103126102c65750519038612fe1565b3d915061325b565b5050915050600090600090600090565b508015612f96565b90916020823d6020116132c5575b816132b460209383612507565b810103126102c65750519038612f8c565b3d91506132a7565b90506020813d6020116132f7575b816132e860209383612507565b81010312610646575138612f26565b3d91506132db565b600090600090600090565b90506020813d602011613334575b8161332560209383612507565b81010312610646575138612e88565b3d9150613318565b1561334357565b608460405162461bcd60e51b815260206004820152603060248201527f4465706f7369747320696e746f20526f636b657420506f6f6c2061726520637560448201527f7272656e746c792064697361626c6564000000000000000000000000000000006064820152fd5b602460206001600160a01b0360005460081c16604051928380927f21f8a7210000000000000000000000000000000000000000000000000000000082527f65dd923ddfc8d8ae6088f80077201d2403cbd565f0ba25e09841e2799ec90bb260048301525afa90811561261557600091613424575090565b90506020813d602011613450575b8161343f60209383612507565b810103126106465761284190612b19565b3d9150613432565b60206001600160a01b0360005460081c16916024604051809481937f21f8a72100000000000000000000000000000000000000000000000000000000835260048301525afa90811561261557600091613424575090565b6134ef9060405161036a816101c560208201947f636f6e74726163742e6164647265737300000000000000000000000000000000865260308301906126cf565b6001600160a01b038116156135015790565b606460405162461bcd60e51b815260206004820152601260248201527f436f6e7472616374206e6f7420666f756e6400000000000000000000000000006044820152fd5b90602460206001600160a01b0361356360405161298b604082612507565b16604051928380927ffd82e9dd0000000000000000000000000000000000000000000000000000000082527fa7c30d79bac38383b63cf527b2a68c8a7efff3ba22dfd5b81d98030643ef0fca60048301525afa90811561261557600091613606575b50806135df575b50816135d6575050565b612de49161496f565b91908183106135f35750612de4915061454b565b908261360091039261454b565b386135cc565b906020823d602011613630575b8161362060209383612507565b810103126102c6575051386135c5565b3d9150613613565b602460206001600160a01b0360005460081c16604051928380927fbd02d0f50000000000000000000000000000000000000000000000000000000082527f6465706f7369742e706f6f6c2e6e6f64652e62616c616e63650000000000000060048301525afa908115612615576000916125e6575090565b602460206001600160a01b0360005460081c16604051928380927fbd02d0f50000000000000000000000000000000000000000000000000000000082527fb869ecac5aab3eca31bf3f499f9eb526669f14aa1402bb5674c73cd5a5b2611f60048301525afa908115612615576000916125e6575090565b602460206001600160a01b0360005460081c16604051928380927fbd02d0f50000000000000000000000000000000000000000000000000000000082527f43d6a8fcdd5ecf01f71d0e1d9b20163adaa8fbb9e896e8263c967735d0ae5ce060048301525afa908115612615576000916125e6575090565b602460206001600160a01b0360005460081c16604051928380927fbd02d0f50000000000000000000000000000000000000000000000000000000082527fe854d579bb35988f8f3715377be8a57a13d9f9db42d0eaf95a3a8f39a96bca4460048301525afa908115612615576000916125e6575090565b60206001600160a01b0360005460081c16916024604051809481937fbd02d0f500000000000000000000000000000000000000000000000000000000835260048301525afa908115612615576000916125e6575090565b6000916001600160a01b03835460081c1691823b1561135d5790604484928360405195869485937fadb353dc000000000000000000000000000000000000000000000000000000008552600485015260248401525af180156102bb576138cf575050565b816138d991612507565b50565b60206001600160a01b0360005460081c16916024604051809481937f7ae1cfca00000000000000000000000000000000000000000000000000000000835260048301525afa90811561261557600091613933575090565b612841915060203d60201161081b5761080d8183612507565b90612de4916040516139a2816101c56020820194856bffffffffffffffffffffffff196034927f6d656761706f6f6c2e6574682e6d6174636865642e6e6f64652e616d6f756e74835260601b1660208201520190565b51902061386b565b9081602091031261064657517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681036106465790565b906000916001600160a01b036139fb604051611165604082612507565b1690604051613a74816101c56020820194856bffffffffffffffffffffffff196035927f6d656761706f6f6c2e6574682e70726f76696465642e6e6f64652e616d6f756e83527f7400000000000000000000000000000000000000000000000000000000000000602084015260601b1660218201520190565b519020916040517f6838444b000000000000000000000000000000000000000000000000000000008152836004820152602081602481865afa9081156107e857917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff613ae69281948891613b5e575b5016612736565b1691813b1561135d576040517f5ba5964900000000000000000000000000000000000000000000000000000000815260048101919091527bffffffffffffffffffffffffffffffffffffffffffffffffffffffff92909216602483015282908290604490829084905af180156102bb576138cf575050565b613b77915060203d6020116113895761137b8183612507565b38613adf565b613ba5577f3676a2bfaf1dbda572dffd9f1bf1596b6bda293af53a4f0eb0ecb236bf64075e90565b7f5a55531ca116b9495f14b748a940f79340b078cefcdd2db09ea1ce8b68bad15b90565b6000906001600160a01b03825460081c1690813b15610d625782916044839260405194859384927febb9d8c90000000000000000000000000000000000000000000000000000000084527f43d6a8fcdd5ecf01f71d0e1d9b20163adaa8fbb9e896e8263c967735d0ae5ce0600485015260248401525af180156102bb576138cf575050565b6000906001600160a01b03825460081c1690813b15610d625782916044839260405194859384927febb9d8c90000000000000000000000000000000000000000000000000000000084527f6465706f7369742e706f6f6c2e6e6f64652e62616c616e636500000000000000600485015260248401525af180156102bb576138cf575050565b6000916001600160a01b03835460081c1691823b1561135d5790604484928360405195869485937febb9d8c9000000000000000000000000000000000000000000000000000000008552600485015260248401525af180156102bb576138cf575050565b612de46fffffffffffffffffffffffffffffffff613d5361379d565b167fffffffffffffffffffffffffffffffff000000000000000000000000000000004360801b161761502c565b612de4613d8b61379d565b7fffffffffffffffffffffffffffffffff0000000000000000000000000000000016436fffffffffffffffffffffffffffffffff161761502c565b63ffffffff8111613dda5763ffffffff1690565b608460405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203360448201527f32206269747300000000000000000000000000000000000000000000000000006064820152fd5b91906000906001600160a01b03613e626040516103ec604082612507565b166040517f6ada7847000000000000000000000000000000000000000000000000000000008152602081600481855afa9081156108575790613eaa918591610909575061333c565b6001600160a01b03613ef2604051613ec3604082612507565b601581527f726f636b65744d656761706f6f6c466163746f7279000000000000000000000060208201526134af565b1694604051957f4e1ccaf10000000000000000000000000000000000000000000000000000000087526001600160a01b03821696876004820152602081602481855afa908115614362578691614343575b50156142ff576020602491604051928380927f74db6b880000000000000000000000000000000000000000000000000000000082528b60048301525afa9081156107e85785916142ba575b5060206001600160a01b03916004604051809481937f14a6bf0f000000000000000000000000000000000000000000000000000000008352165afa9081156107e8578591614288575b5061421e5760405161402d816101c56020820194856bffffffffffffffffffffffff19602f927f6e6f64652e6465706f7369742e6372656469742e62616c616e63650000000000835260601b16601b8201520190565b5190208461403a82613814565b106141da5760049161404e86602093613cd3565b61408d60405161405f604082612507565b601181527f726f636b65744e6f64654d616e61676572000000000000000000000000000000848201526134af565b50604051928380927f0de705b50000000000000000000000000000000000000000000000000000000082525afa9081156108fe5783916141a8575b506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690813b1561135d576040517f94bf804d000000000000000000000000000000000000000000000000000000008152670de0b6b3a764000091860291909104850360048201526001600160a01b0392909216602483015282908290604490829084905af180156102bb57917f77982616940619ddbda4afe3675280fff7c605d31503336add3633fbea69d8ba9391604093614198575b50508151908152426020820152a2565b816141a291612507565b38614188565b90506020813d6020116141d2575b816141c360209383612507565b81010312610d625751386140c8565b3d91506141b6565b606460405162461bcd60e51b815260206004820152601f60248201527f416d6f756e7420657863656564732063726564697420617661696c61626c65006044820152fd5b608460405162461bcd60e51b815260206004820152602860248201527f43616e6e6f7420776974686472617720637265646974207768696c652064656260448201527f74206578697374730000000000000000000000000000000000000000000000006064820152fd5b90506020813d6020116142b2575b816142a360209383612507565b81010312611a24575138613fd7565b3d9150614296565b90506020813d6020116142f7575b816142d560209383612507565b81010312611a245760206142f06001600160a01b0392612b19565b9150613f8e565b3d91506142c8565b606460405162461bcd60e51b815260206004820152601960248201527f4d656761706f6f6c206d757374206265206465706c6f796564000000000000006044820152fd5b61435c915060203d60201161081b5761080d8183612507565b38613f43565b6040513d88823e3d90fd5b6143756150b1565b3481116144a0575b6143878134612736565b9060009080614424575b5090806143a3575b5050612de461527e565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016803b15610d625782906004604051809481937f98ea5fca0000000000000000000000000000000000000000000000000000000083525af180156102bb57156143995761441a828092612507565b6102c65780614399565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016803b15610d625782906004604051809481937f6c985a880000000000000000000000000000000000000000000000000000000083525af180156102bb5715614391578161449a91612507565b38614391565b503461437d565b604051906144b6606083612507565b602182527f6c000000000000000000000000000000000000000000000000000000000000006040837f726f636b657444414f50726f746f636f6c53657474696e67734d696e69706f6f60208201520152565b805182101561451c5760209160051b010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060046000926001600160a01b0361459960405161456a604082612507565b601381527f726f636b65744d696e69706f6f6c51756575650000000000000000000000000060208201526134af565b169060206001600160a01b036145b56145b06144a7565b6134af565b16604051948580927f3469f7b40000000000000000000000000000000000000000000000000000000082525afa9283156107e857859361493b575b50614602836145fd612548565b612c9b565b8015614933579160248284889586951161492b575b5060405197889384927f7e0e497b00000000000000000000000000000000000000000000000000000000845260048401525af1938415612298578194614858575b50835180614668575b5050509050565b8261467291612b96565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690813b15610d625782916024839260405194859384927f3bed33ce00000000000000000000000000000000000000000000000000000000845260048401525af180156102bb578290614848575b8291505b8551821015614830576001600160a01b036147088388614508565b5116803b1561135d576040517fd0e30db0000000000000000000000000000000000000000000000000000000008152848160048189865af180156107e85790859161481b575b50506020600491604051928380927fd2ceebd10000000000000000000000000000000000000000000000000000000082525afa9081156108575784916147e7575b5061479c906001926126fa565b916001600160a01b036147af8289614508565b51167fa1811054b7d96716259cff0d366c2f6405951e0efe00c8db3e237cbf77fe7be960408051888152426020820152a201906146ed565b905060203d8111614814575b6147fd8183612507565b602082600092810103126102c6575051600161478f565b503d6147f3565b8161482591612507565b61135d57833861474e565b9250505061483f919250613c4e565b80388080614661565b61485191612507565b38816146e9565b9093503d8085833e61486a8183612507565b810190602081830312611a245780519067ffffffffffffffff821161135957019080601f83011215611a245781519167ffffffffffffffff83116148fe578260051b90604051936148be6020840186612507565b84526020808501928201019283116114c157602001905b8282106148e6575050509238614658565b602080916148f384612b19565b8152019101906148d5565b6024867f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b905038614617565b505050509050565b9092506020813d602011614967575b8161495760209383612507565b81010312611a24575191386145f0565b3d915061494a565b6001600160a01b03614988604051610faf604082612507565b166040517ffd82e9dd0000000000000000000000000000000000000000000000000000000081527f5a55531ca116b9495f14b748a940f79340b078cefcdd2db09ea1ce8b68bad15b6004820152602081602481855afa90811561261557600091614ffa575b506040517ffd82e9dd0000000000000000000000000000000000000000000000000000000081527f3676a2bfaf1dbda572dffd9f1bf1596b6bda293af53a4f0eb0ecb236bf64075e6004820152602081602481865afa90811561261557600091614fc8575b50906001600160a01b036020614a666136af565b966004604051809481937f1aff58eb000000000000000000000000000000000000000000000000000000008352165afa90811561261557600091614f96575b509293916000918293614ab6612548565b928496859886946001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016905b858710614c62575b5050505050505050614b0290613c4e565b6001600160a01b0360005460081c1693843b15610646576000946044869260405197889384927fe2a4853a0000000000000000000000000000000000000000000000000000000084527fb869ecac5aab3eca31bf3f499f9eb526669f14aa1402bb5674c73cd5a5b2611f600485015260248401525af190811561261557612de494614b9292614c51575b50613bc9565b614b9a61379d565b9015614c38576fffffffffffffffffffffffffffffffff4316915b15614bfd57506fffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffff000000000000000000000000000000008143165b60801b1691161761502c565b7fffffffffffffffffffffffffffffffff000000000000000000000000000000006fffffffffffffffffffffffffffffffff9160801c614bf1565b6fffffffffffffffffffffffffffffffff811691614bb5565b6000614c5c91612507565b38614b8c565b9091929394969b9897959981159c8d809e614f8e575b614f82576001860180871161270757614c9287918d612c62565b1415809e81614f7a575b50614f71575b8d1580614f69575b614f60575b614cb88e613b7d565b90604051987f4fd8f054000000000000000000000000000000000000000000000000000000008a528260048b015260808a6024818a5afa998a156126155760009a614f40575b5063ffffffff60608b0151169166038d7ea4c6800083029280840466038d7ea4c68000149015171561270757828110614f3357863b1561064657604051907f3bed33ce000000000000000000000000000000000000000000000000000000008252836004830152600082602481838c5af190811561261557614d87928592614f22575b50612736565b996001600160a01b0381511663ffffffff602083015116813b15610646578491602460009260405194859384927f7685e80b00000000000000000000000000000000000000000000000000000000845260048401525af1801561261557614f11575b506001600160a01b038151167f21d4fea1e00248ceff22105d25fec21f17b7134ab4881761ab27ac2d4249fdee60408051868152426020820152a2604051937fdc5be997000000000000000000000000000000000000000000000000000000008552600485015260808460248160008c5af193841561261557604066038d7ea4c680009263ffffffff92600197614ef5575b5001511602019a019a019c600014614ec457507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01946001809a5b019596949392919096614ae9565b999a5094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01936001809b614eb6565b614f0c9060803d8111611a8757611a788183612507565b614e7b565b6000614f1c91612507565b38614de9565b6000614f2d91612507565b38614d81565b509a9b9e50505099614af1565b614f59919a5060803d8111611a8757611a788183612507565b9838614cfe565b60019d50614caf565b508615614caa565b60009d50614ca2565b905038614c9c565b50998698999c50614af1565b508615614c78565b906020823d602011614fc0575b81614fb060209383612507565b810103126102c657505138614aa5565b3d9150614fa3565b90506020813d602011614ff2575b81614fe360209383612507565b81010312610646575138614a52565b3d9150614fd6565b90506020813d602011615024575b8161501560209383612507565b810103126106465751386149ed565b3d9150615008565b6000906001600160a01b03825460081c1690813b15610d625782916044839260405194859384927fe2a4853a0000000000000000000000000000000000000000000000000000000084527fe854d579bb35988f8f3715377be8a57a13d9f9db42d0eaf95a3a8f39a96bca44600485015260248401525af180156102bb576138cf575050565b6001600160a01b036150f96040516150ca604082612507565b602081527f726f636b657444414f50726f746f636f6c53657474696e67734e6574776f726b60208201526134af565b16600460206001600160a01b03615145604051615117604082612507565b601581527f726f636b65744e6574776f726b42616c616e6365730000000000000000000000848201526134af565b1692604051928380927fe28767130000000000000000000000000000000000000000000000000000000082525afa9081156126155760009161524c575b50600460206001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163193604051928380927f964d042c0000000000000000000000000000000000000000000000000000000082525afa90811561261557600091615212575b50670de0b6b3a76400009161520291612b96565b0490808211612c25575050600090565b90506020813d602011615244575b8161522d60209383612507565b810103126106465751670de0b6b3a76400006151ee565b3d9150615220565b90506020813d602011615276575b8161526760209383612507565b81010312610646575138615182565b3d915061525a565b6001600160a01b036152976040516103ec604082612507565b166040517f47fa434a000000000000000000000000000000000000000000000000000000008152602081600481855afa9081156126155760009161567f575b50156138d957602460206001600160a01b036152f960405161298b604082612507565b16604051928380927ffd82e9dd0000000000000000000000000000000000000000000000000000000082527fa7c30d79bac38383b63cf527b2a68c8a7efff3ba22dfd5b81d98030643ef0fca60048301525afa9081156126155760009161564d575b50156155375761537260405161456a604082612507565b506001600160a01b036153866145b06144a7565b16604051907f3b474a65000000000000000000000000000000000000000000000000000000008252602082600481865afa91821561261557600092615502575b506020600491604051928380927f3469f7b40000000000000000000000000000000000000000000000000000000082525afa8015612615576000906154cf575b6004915060206154226154198334612c9b565b926145fd612548565b94604051938480927ff19b41060000000000000000000000000000000000000000000000000000000082525afa80156126155760009061549b575b61546792506126fa565b91808311615493575b5080821161548b575b50806154825750565b612de49061454b565b905038615479565b915038615470565b506020823d6020116154c7575b816154b560209383612507565b8101031261064657615467915161545d565b3d91506154a8565b6020823d6020116154fa575b816154e860209383612507565b810103126102c6575060049051615406565b3d91506154db565b90916020823d60201161552f575b8161551d60209383612507565b810103126102c65750519060206153c6565b3d9150615510565b604051907f3b474a65000000000000000000000000000000000000000000000000000000008252602082600481845afa91821561261557600092615619575b506040517ff19b4106000000000000000000000000000000000000000000000000000000008152602081600481855afa8015612615576000906155e5575b6155cb91506801bc16d674ec8000003404906126fa565b918083116155dd5750816135d6575050565b9150386135cc565b506020813d602011615611575b816155ff60209383612507565b81010312610646576155cb90516155b4565b3d91506155f2565b90916020823d602011615645575b8161563460209383612507565b810103126102c65750519038615576565b3d9150615627565b90506020813d602011615677575b8161566860209383612507565b8101031261064657513861535b565b3d915061565b565b615698915060203d60201161081b5761080d8183612507565b386152d656fea26469706673582212208dd5003687e3781407bc3a73ee56aad724c9a77056eaf616c7b60f77ef68cc5364736f6c634300081e00330000000000000000000000001d8f8f00cfa6758d7be78336684788fb0ee0fa46
Deployed Bytecode
0x6080604052600436101561001257600080fd5b6000803560e01c806312065fe0146124785780631666f5e21461237c5780631b7dd4c0146122db5780631e35fed8146122c05780631eddb626146122a557806322b1751d146120d4578063258260951461205d57806327afc6f5146120425780633350677b1461202757806342e6dfa214611ff657806354fd4d5014611fd657806360be2e1c14611ef057806363a5db9e14611cf157806372f5158d14611ba8578063791d25b114611b8d5780637aab9e1614611af25780637d9d607414611612578063888b042f146115f75780639a8dd16f14610d915780639e2c0c1914610d6e578063a559a64514610bc6578063a673c8e114610b96578063a9a9482214610a73578063b7013dc114610a02578063c095415d14610961578063c6f20e6d14610928578063d0e30db0146103b4578063db82047b146102c95763ef6f886a1461015c57600080fd5b346102c65760206003193601126102c6576101fe6101f960405160208101906101f1816101c533856bffffffffffffffffffffffff19601f927f6e6f64652e657869737473000000000000000000000000000000000000000000835260601b16600b8201520190565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101835282612507565b5190206138dc565b612d27565b6102196001600160a01b036102116133ad565b163014612621565b602460206001600160a01b03835460081c16604051928380927f5b49ff620000000000000000000000000000000000000000000000000000000082523360048301525afa80156102bb57829061027c575b61027991506004359033613e44565b80f35b506020813d6020116102b3575b8161029660209383612507565b810103126102af576102aa61027991612b19565b61026a565b5080fd5b3d9150610289565b6040513d84823e3d90fd5b80fd5b50806003193601126102c6576102e86001600160a01b036102116133ad565b61037a6001600160a01b03610372604051610304604082612507565b600f81527f726f636b6574546f6b656e524554480000000000000000000000000000000000602082015260405161036a816101c560208201947f636f6e74726163742e6164647265737300000000000000000000000000000000865260308301906126cf565b519020613458565b163314612621565b6040513481524260208201527f3a6614e80d02b57255cbb1f8305fbeca53d7e05a4b779d40627919660851292560403392a261027961436d565b50806003193601126102c6576103d36001600160a01b036102116133ad565b6001600160a01b0361041b6040516103ec604082612507565b602081527f726f636b657444414f50726f746f636f6c53657474696e67734465706f73697460208201526134af565b166040517f6ada7847000000000000000000000000000000000000000000000000000000008152602081600481855afa80156108fe57610462918491610909575b5061333c565b6040517f035cf142000000000000000000000000000000000000000000000000000000008152602081600481855afa9081156108fe5783916108cc575b503410610862578190346104b1612548565b016040517ffd6ce89e000000000000000000000000000000000000000000000000000000008152602081600481865afa908115610857578491610822575b50808211610653575b50506020600491604051928380927f0de705b50000000000000000000000000000000000000000000000000000000082525afa9081156102bb578291610619575b506001600160a01b037f000000000000000000000000ae78736cd615f374d3085123a210448e74fc639316803b15610615576040517f94bf804d000000000000000000000000000000000000000000000000000000008152670de0b6b3a76400003493840204909203600483015233602483015282908290604490829084905af180156102bb57610600575b506040513481524260208201527f7aa1a8eb998c779420645fc14513bf058edb347d95c2fc2e6845bdc22f88863160403392a261027961436d565b8161060a91612507565b6102c65780386105c5565b5050fd5b9150506020813d60201161064b575b8161063560209383612507565b810103126106465781905138610539565b600080fd5b3d9150610628565b909192506040517f47fa434a000000000000000000000000000000000000000000000000000000008152602081600481875afa9081156107e85785916107f3575b50156107475760049060206001600160a01b036106e66040516106b8604082612507565b601381527f726f636b65744d696e69706f6f6c517565756500000000000000000000000000848201526134af565b16604051938480927fe60b40bf0000000000000000000000000000000000000000000000000000000082525afa9182156107e85785926107b2575b5061073161073792610731613726565b906126fa565b10610747578190602060046104f8565b60405162461bcd60e51b815260206004820152603f60248201527f546865206465706f73697420706f6f6c2073697a65206166746572206465706f60448201527f736974696e67206578636565647320746865206d6178696d756d2073697a65006064820152608490fd5b91506020823d6020116107e0575b816107cd60209383612507565b8101031261064657905190610731610721565b3d91506107c0565b6040513d87823e3d90fd5b610815915060203d60201161081b575b61080d8183612507565b8101906126b7565b38610694565b503d610803565b9350506020833d60201161084f575b8161083e60209383612507565b8101031261064657839251386104ef565b3d9150610831565b6040513d86823e3d90fd5b608460405162461bcd60e51b815260206004820152603a60248201527f546865206465706f736974656420616d6f756e74206973206c6573732074686160448201527f6e20746865206d696e696d756d206465706f7369742073697a650000000000006064820152fd5b90506020813d6020116108f6575b816108e760209383612507565b8101031261064657513861049f565b3d91506108da565b6040513d85823e3d90fd5b610922915060203d60201161081b5761080d8183612507565b3861045c565b50346102c657806003193601126102c6576060610943612e09565b906001600160a01b0360405193168352151560208301526040820152f35b50806003193601126102c6576109806001600160a01b036102116133ad565b6102796001600160a01b0361037260405161099c604082612507565b600b81527f726f636b65745661756c74000000000000000000000000000000000000000000602082015260405161036a816101c560208201947f636f6e74726163742e6164647265737300000000000000000000000000000000865260308301906126cf565b50346102c657806003193601126102c657610a1b612548565b90610a24613638565b91818382039312818412811691841390151617610a4657602082604051908152f35b807f4e487b7100000000000000000000000000000000000000000000000000000000602492526011600452fd5b50346102c65760606003193601126102c657610279610a90612493565b610aed610ae860405160208101906101f1816101c533856bffffffffffffffffffffffff196023927f6d656761706f6f6c2e6578697374730000000000000000000000000000000000835260601b16600f8201520190565b612ace565b610b006001600160a01b036102116133ad565b610b0c602435826139de565b60405190610b8a82610b5e6020820193846bffffffffffffffffffffffff196034927f6d656761706f6f6c2e6574682e6d6174636865642e6e6f64652e616d6f756e74835260601b1660208201520190565b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101845283612507565b60443591519020613cd3565b50346102c65760206003193601126102c657610bbb6001600160a01b036102116133ad565b610279600435612d72565b50346102c65760406003193601126102c6576024610be2612493565b610c3a6101f960405160208101906101f1816101c587856bffffffffffffffffffffffff19601f927f6e6f64652e657869737473000000000000000000000000000000000000000000835260601b16600b8201520190565b610c4d6001600160a01b036102116133ad565b60206001600160a01b03845460081c16604051938480927f5b49ff620000000000000000000000000000000000000000000000000000000082526001600160a01b03861660048301525afa9182156108fe578392610d2e575b506001600160a01b0382163303610cc4576102799160243591613e44565b608460405162461bcd60e51b815260206004820152602660248201527f4d7573742062652063616c6c65642066726f6d207769746864726177616c206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152fd5b9091506020813d602011610d66575b81610d4a60209383612507565b81010312610d6257610d5b90612b19565b9038610ca6565b8280fd5b3d9150610d3d565b50346102c657806003193601126102c6576020610d89612ca5565b604051908152f35b50346102c65760806003193601126102c657600435610dae6124a9565b90604435606435918215159283810361135957610e19610ae860405160208101906101f1816101c533856bffffffffffffffffffffffff196023927f6d656761706f6f6c2e6578697374730000000000000000000000000000000000835260601b16600f8201520190565b610e2c6001600160a01b036102116133ad565b66038d7ea4c6800082066115b35766038d7ea4c68000830661156f57604051907f70dabc9e0000000000000000000000000000000000000000000000000000000082526020826004818a335af19182156113d0578792611533575b50866001600160a01b03610ed1604051610ea2604082612507565b601181527f726f636b65744e6f64654d616e6167657200000000000000000000000000000060208201526134af565b1682156114c557803b156102af578180916024604051809481937fc220f0920000000000000000000000000000000000000000000000000000000083526001600160a01b038a1660048401525af180156102bb576114ac575b50505b610f3681613b7d565b9087610f4a66038d7ea4c680008604613dc6565b92610f5d66038d7ea4c680008804613dc6565b60405190610f6a826124bc565b33825263ffffffff602083019b169a8b815263ffffffff604084019716875263ffffffff60608401921682526001600160a01b03610fde604051610faf604082612507565b601181527f6c696e6b65644c69737453746f7261676500000000000000000000000000000060208201526134af565b1696873b156113595763ffffffff8094926001600160a01b038294604051987fea58ecf5000000000000000000000000000000000000000000000000000000008a5260048a015251166024880152511660448601525116606484015251166084820152818160a48183885af180156102bb57611497575b506001600160a01b03815460081c16803b156102af578180916044604051809481937fadb353dc0000000000000000000000000000000000000000000000000000000083527f43d6a8fcdd5ecf01f71d0e1d9b20163adaa8fbb9e896e8263c967735d0ae5ce060048401528c60248401525af180156102bb5761147e575b50506024916020916000146113db57604051928380927ffd82e9dd0000000000000000000000000000000000000000000000000000000082527f5a55531ca116b9495f14b748a940f79340b078cefcdd2db09ea1ce8b68bad15b60048301525afa80156113d057879061139d575b6001915014611390575b856001600160a01b03611194604051611165604082612507565b601681527f726f636b65744e6574776f726b536e617073686f74730000000000000000000060208201526134af565b16604051602081019061120d816101c587856bffffffffffffffffffffffff196035927f6d656761706f6f6c2e6574682e70726f76696465642e6e6f64652e616d6f756e83527f7400000000000000000000000000000000000000000000000000000000000000602084015260601b1660218201520190565b5190206040517f6838444b000000000000000000000000000000000000000000000000000000008152816004820152602081602481865afa90811561085757867bffffffffffffffffffffffffffffffffffffffffffffffffffffffff809361127e938891611361575b50166126fa565b16823b1561135d576040517f5ba5964900000000000000000000000000000000000000000000000000000000815260048101929092527bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660248201529082908290604490829084905af180156102bb57611344575b50506112ff6113059284612736565b9061394c565b604051928352602083015260408201524260608201527f4040156d881bd2ba289490b90281b228e6c221621274ce90999669f12d74ddfb60803392a280f35b8161134e91612507565b6113595785386112f0565b8580fd5b8380fd5b611383915060203d602011611389575b61137b8183612507565b8101906139aa565b38611277565b503d611371565b611398613d80565b61114b565b506020813d6020116113c8575b816113b760209383612507565b810103126106465760019051611141565b3d91506113aa565b6040513d89823e3d90fd5b604051928380927ffd82e9dd0000000000000000000000000000000000000000000000000000000082527f3676a2bfaf1dbda572dffd9f1bf1596b6bda293af53a4f0eb0ecb236bf64075e60048301525afa80156113d057879061144b575b600191500361114b57611398613d37565b506020813d602011611476575b8161146560209383612507565b81010312610646576001905161143a565b3d9150611458565b8161148891612507565b6114935787386110d3565b8780fd5b816114a191612507565b611493578738611055565b816114b691612507565b6114c1578638610f2a565b8680fd5b803b156102af578180916024604051809481937f4395fb740000000000000000000000000000000000000000000000000000000083526001600160a01b038a1660048401525af180156102bb5761151e575b5050610f2d565b8161152891612507565b6114c1578638611517565b9091506020813d602011611567575b8161154f60209383612507565b810103126114c15761156090612b19565b9038610e87565b3d9150611542565b606460405162461bcd60e51b815260206004820152601860248201527f496e76616c69642072657175657374656420616d6f756e7400000000000000006044820152fd5b606460405162461bcd60e51b815260206004820152601760248201527f496e76616c696420737570706c69656420616d6f756e740000000000000000006044820152fd5b50346102c657806003193601126102c6576020610d89612ba9565b50346102c65760606003193601126102c65761162c612493565b6116346124a9565b60443590811515820361135d57611699610ae860405160208101906101f1816101c533856bffffffffffffffffffffffff196023927f6d656761706f6f6c2e6578697374730000000000000000000000000000000000835260601b16600f8201520190565b6116ac6001600160a01b036102116133ad565b6001600160a01b036116c5604051610faf604082612507565b1691604051916040830183811067ffffffffffffffff821117611ac55760405233835263ffffffff166020830152846116fd82613b7d565b6040517fed8ef8fb0000000000000000000000000000000000000000000000000000000081526004810182905284516001600160a01b0316602482015260208086015163ffffffff1660448301529095919086606481855afa9586156108fe578396611a8e575b50604051957ff3358a3a000000000000000000000000000000000000000000000000000000008752816004880152806024880152608087604481865afa968715610857578497611a5d575b506040517f45134808000000000000000000000000000000000000000000000000000000008152826004820152602081602481875afa9081156107e8578591611a28575b501494823b1561135d576040517f41b93d1b000000000000000000000000000000000000000000000000000000008152600481019290925280516001600160a01b031660248301526020015163ffffffff1660448201529082908290606490829084905af180156102bb57611a0f575b505063ffffffff60608401511666038d7ea4c6800081029080820466038d7ea4c6800014901517156119e25761189890613bc9565b156119cc57836001600160a01b036118b7604051610ea2604082612507565b16803b156102af578180916024604051809481937fa90e35a60000000000000000000000000000000000000000000000000000000083526001600160a01b038b1660048401525af180156102bb576119b7575b505063ffffffff916040916119aa575b01511666038d7ea4c6800081029080820466038d7ea4c68000149015171561197d5761194590613c4e565b7f795bf47f48111f2d01d87912d6b77fa833a62f0c4e2221ae9ecd474ec50d8b3360206001600160a01b03604051934285521692a280f35b6024837f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b6119b2613d80565b61191a565b816119c191612507565b61135d57833861190a565b63ffffffff916040911561191a576119b2613d37565b6024867f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b81611a1991612507565b611a24578438611863565b8480fd5b9450506020843d602011611a55575b81611a4460209383612507565b8101031261064657889351386117f3565b3d9150611a37565b611a8091975060803d608011611a87575b611a788183612507565b810190612b3e565b95386117af565b503d611a6e565b925094506020823d602011611abd575b81611aab60209383612507565b81010312610646578691519438611764565b3d9150611a9e565b6024877f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b50346102c65760406003193601126102c657610279611b0f612493565b60243590611b6b610ae860405160208101906101f1816101c533856bffffffffffffffffffffffff196023927f6d656761706f6f6c2e6578697374730000000000000000000000000000000000835260601b16600f8201520190565b611b7e6001600160a01b036102116133ad565b611b88828261394c565b6139de565b50346102c657806003193601126102c6576020610d896136af565b50806003193601126102c657611bc76001600160a01b036102116133ad565b6040517f6d656761706f6f6c2e6578697374730000000000000000000000000000000000602082019081523360601b6bffffffffffffffffffffffff1916602f830152611c1b916101f181604381016101c5565b8015611ca5575b15611c61576040513481524260208201527f3a6614e80d02b57255cbb1f8305fbeca53d7e05a4b779d40627919660851292560403392a261027961436d565b606460405162461bcd60e51b815260206004820152600e60248201527f496e76616c69642063616c6c65720000000000000000000000000000000000006044820152fd5b50611cec60405160208101907f6d696e69706f6f6c2e657869737473000000000000000000000000000000000082523360601b602f820152602381526101f1604382612507565b611c22565b50346102c65760206003193601126102c657600435611d196001600160a01b036102116133ad565b611d356001600160a01b03610372604051610304604082612507565b611d3d612ba9565b8111611e8657816001600160a01b037f0000000000000000000000003bdc69c4e5e13e52a65f5583c23efb9636b469d616803b156102af578180916024604051809481937f3bed33ce0000000000000000000000000000000000000000000000000000000083528860048401525af180156102bb57611e71575b506001600160a01b037f000000000000000000000000ae78736cd615f374d3085123a210448e74fc639316803b156102af578183916004604051809481937f6c985a880000000000000000000000000000000000000000000000000000000083525af180156102bb57611e5c575b50506040519081524260208201527f992f462cfb62e164bd03bf07baf2cffce83fbd9370cae10635842b202001212060403392a280f35b81611e6691612507565b6102af578138611e25565b81611e7b91612507565b6102af578138611db7565b608460405162461bcd60e51b815260206004820152602a60248201527f496e73756666696369656e74206578636573732062616c616e636520666f722060448201527f7769746864726177616c000000000000000000000000000000000000000000006064820152fd5b50346102c65760406003193601126102c657610279611f0d612493565b611f65610ae860405160208101906101f1816101c533856bffffffffffffffffffffffff196023927f6d656761706f6f6c2e6578697374730000000000000000000000000000000000835260601b16600f8201520190565b611f786001600160a01b036102116133ad565b60405190611fca82610b5e6020820193846bffffffffffffffffffffffff19602f927f6e6f64652e6465706f7369742e6372656469742e62616c616e63650000000000835260601b16601b8201520190565b6024359151902061386b565b50346102c657806003193601126102c65760ff6020915416604051908152f35b50346102c657806003193601126102c6576020610d8961201f61201761296e565b610731612a1e565b610731612ca5565b50346102c657806003193601126102c6576020610d89612a1e565b50346102c657806003193601126102c6576020610d8961296e565b50346102c65760206003193601126102c6576020610d8961207c612493565b6040516120cc816101c586820194856bffffffffffffffffffffffff19602f927f6e6f64652e6465706f7369742e6372656469742e62616c616e63650000000000835260601b16601b8201520190565b519020613814565b5060206003193601126102c6576120f46001600160a01b036102116133ad565b6121766001600160a01b03610372604051612110604082612507565b601181527f726f636b65744e6f64654465706f736974000000000000000000000000000000602082015260405161036a816101c560208201947f636f6e74726163742e6164647265737300000000000000000000000000000000865260308301906126cf565b34612212575b806001600160a01b03815460081c16803b1561220f578180916044604051809481937fadb353dc0000000000000000000000000000000000000000000000000000000083527f6465706f7369742e706f6f6c2e6e6f64652e62616c616e636500000000000000600484015260043560248401525af180156102bb576121fe5750f35b8161220891612507565b6102c65780f35b50fd5b6001600160a01b037f0000000000000000000000003bdc69c4e5e13e52a65f5583c23efb9636b469d61681813b156102c65780600492604051938480927f98ea5fca00000000000000000000000000000000000000000000000000000000825234905af1801561229857612288575b505061217c565b61229191612507565b3881612281565b50604051903d90823e3d90fd5b50346102c657806003193601126102c6576020610d89612743565b50346102c657806003193601126102c6576020610d89613638565b50806003193601126102c6576122fa6001600160a01b036102116133ad565b61037a6001600160a01b03610372604051612316604082612507565b601481527f726f636b657441756374696f6e4d616e61676572000000000000000000000000602082015260405161036a816101c560208201947f636f6e74726163742e6164647265737300000000000000000000000000000000865260308301906126cf565b50346102c65760206003193601126102c6576004356123a46001600160a01b036102116133ad565b6123af81151561266c565b6001600160a01b036123c86040516103ec604082612507565b166040517f47fa434a000000000000000000000000000000000000000000000000000000008152602081600481855afa908115610857578491612459575b50156124155761027991613545565b606460405162461bcd60e51b815260206004820152602060248201527f4465706f7369742061737369676e6d656e7473206172652064697361626c65646044820152fd5b612472915060203d60201161081b5761080d8183612507565b38612406565b50346102c657806003193601126102c6576020610d89612548565b600435906001600160a01b038216820361064657565b6024359063ffffffff8216820361064657565b6080810190811067ffffffffffffffff8211176124d857604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff8211176124d857604052565b6040517f35ee5f87000000000000000000000000000000000000000000000000000000008152602060048201819052601160248301527f726f636b65744465706f736974506f6f6c0000000000000000000000000000006044830152816064817f0000000000000000000000003bdc69c4e5e13e52a65f5583c23efb9636b469d66001600160a01b03165afa908115612615576000916125e6575090565b90506020813d60201161260d575b8161260160209383612507565b81010312610646575190565b3d91506125f4565b6040513d6000823e3d90fd5b1561262857565b606460405162461bcd60e51b815260206004820152601c60248201527f496e76616c6964206f72206f7574646174656420636f6e7472616374000000006044820152fd5b1561267357565b606460405162461bcd60e51b815260206004820152601660248201527f4d7573742061737369676e206174206c656173742031000000000000000000006044820152fd5b90816020910312610646575180151581036106465790565b9081519160005b8381106126e7575050016000815290565b80602080928401015181850152016126d6565b9190820180921161270757565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b9190820391821161270757565b6001600160a01b0361275c6040516103ec604082612507565b166040517f6ada7847000000000000000000000000000000000000000000000000000000008152602081600481855afa9081156126155760009161294f575b5015612949576127a9612548565b6040517ffd6ce89e000000000000000000000000000000000000000000000000000000008152602081600481865afa90811561261557600091612917575b50600460208294604051928380927f47fa434a0000000000000000000000000000000000000000000000000000000082525afa908115612615576000916128f8575b5061284b575b50818110156128445761284191612736565b90565b5050600090565b909150600460206001600160a01b0361286b6040516106b8604082612507565b16604051928380927fe60b40bf0000000000000000000000000000000000000000000000000000000082525afa908115612615576000916128c4575b506128b5906128bd926126fa565b610731613726565b903861282f565b90506020813d6020116128f0575b816128df60209383612507565b8101031261064657516128bd6128a7565b3d91506128d2565b612911915060203d60201161081b5761080d8183612507565b38612829565b906020823d602011612941575b8161293160209383612507565b810103126102c6575051386127e7565b3d9150612924565b50600090565b612968915060203d60201161081b5761080d8183612507565b3861279b565b602460206001600160a01b036129b960405161298b604082612507565b601381527f61646472657373517565756553746f7261676500000000000000000000000000848201526134af565b16604051928380927ffd82e9dd0000000000000000000000000000000000000000000000000000000082527fa7c30d79bac38383b63cf527b2a68c8a7efff3ba22dfd5b81d98030643ef0fca60048301525afa908115612615576000916125e6575090565b602460206001600160a01b03612a69604051612a3b604082612507565b601181527f6c696e6b65644c69737453746f72616765000000000000000000000000000000848201526134af565b16604051928380927ffd82e9dd0000000000000000000000000000000000000000000000000000000082527f5a55531ca116b9495f14b748a940f79340b078cefcdd2db09ea1ce8b68bad15b60048301525afa908115612615576000916125e6575090565b15612ad557565b606460405162461bcd60e51b815260206004820152601060248201527f496e76616c6964206d656761706f6f6c000000000000000000000000000000006044820152fd5b51906001600160a01b038216820361064657565b519063ffffffff8216820361064657565b9081608091031261064657612b8e606060405192612b5b846124bc565b612b6481612b19565b8452612b7260208201612b2d565b6020850152612b8360408201612b2d565b604085015201612b2d565b606082015290565b8181029291811591840414171561270757565b600460206001600160a01b03612bc66040516106b8604082612507565b16604051928380927fe60b40bf0000000000000000000000000000000000000000000000000000000082525afa801561261557600090612c2e575b612c0e9150610731613726565b612c16612548565b90818110612c25575050600090565b61284191612736565b506020813d602011612c5a575b81612c4860209383612507565b8101031261064657612c0e9051612c01565b3d9150612c3b565b8115612c6c570690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b8115612c6c570490565b602460206001600160a01b03612cc2604051612a3b604082612507565b16604051928380927ffd82e9dd0000000000000000000000000000000000000000000000000000000082527f3676a2bfaf1dbda572dffd9f1bf1596b6bda293af53a4f0eb0ecb236bf64075e60048301525afa908115612615576000916125e6575090565b15612d2e57565b606460405162461bcd60e51b815260206004820152600c60248201527f496e76616c6964206e6f646500000000000000000000000000000000000000006044820152fd5b612d7d81151561266c565b6001600160a01b03612d966040516103ec604082612507565b166040517f47fa434a000000000000000000000000000000000000000000000000000000008152602081600481855afa90811561261557600091612dea575b5015612de657612de491613545565b565b5050565b612e03915060203d60201161081b5761080d8183612507565b38612dd5565b602460206001600160a01b03612e2660405161298b604082612507565b16604051928380927ffd82e9dd0000000000000000000000000000000000000000000000000000000082527fa7c30d79bac38383b63cf527b2a68c8a7efff3ba22dfd5b81d98030643ef0fca60048301525afa9081156126155760009161330a575b506132ff576001600160a01b03612ea6604051610faf604082612507565b166001600160a01b03612ec06040516103ec604082612507565b16916040517ffd82e9dd0000000000000000000000000000000000000000000000000000000081527f5a55531ca116b9495f14b748a940f79340b078cefcdd2db09ea1ce8b68bad15b6004820152602081602481865afa908115612615576000916132cd575b50604051907ffd82e9dd0000000000000000000000000000000000000000000000000000000082527f3676a2bfaf1dbda572dffd9f1bf1596b6bda293af53a4f0eb0ecb236bf64075e6004830152602082602481875afa91821561261557600092613299575b5015908180613291575b61328157612fa26136af565b604051907f1aff58eb0000000000000000000000000000000000000000000000000000000082526020826004818a5afa9182156126155760009261324d575b506001820180831161270757612ff691612c62565b1415809281613245575b5061323c575b81159081613233575b5061322b575b608061302082613b7d565b6024604051809681937f4fd8f05400000000000000000000000000000000000000000000000000000000835260048301525afa9283156126155760009361320a575b506040517f35ee5f87000000000000000000000000000000000000000000000000000000008152602060048201819052601160248301527f726f636b65744465706f736974506f6f6c0000000000000000000000000000006044830152816064817f0000000000000000000000003bdc69c4e5e13e52a65f5583c23efb9636b469d66001600160a01b03165afa908115612615576000916131d8575b5063ffffffff6060850151169066038d7ea4c6800082029180830466038d7ea4c68000149015171561270757600491602091101595604051928380927f47fa434a0000000000000000000000000000000000000000000000000000000082525afa908115612615576000916131b9575b50156131b0575b6001600160a01b039061318661379d565b90156131a7576fffffffffffffffffffffffffffffffff16925b5116929190565b60801c926131a0565b60009350613175565b6131d2915060203d60201161081b5761080d8183612507565b3861316e565b90506020813d602011613202575b816131f360209383612507565b810103126106465751386130fe565b3d91506131e6565b61322491935060803d608011611a8757611a788183612507565b9138613062565b506001613015565b9050153861300f565b60009150613006565b905038613000565b90916020823d602011613279575b8161326860209383612507565b810103126102c65750519038612fe1565b3d915061325b565b5050915050600090600090600090565b508015612f96565b90916020823d6020116132c5575b816132b460209383612507565b810103126102c65750519038612f8c565b3d91506132a7565b90506020813d6020116132f7575b816132e860209383612507565b81010312610646575138612f26565b3d91506132db565b600090600090600090565b90506020813d602011613334575b8161332560209383612507565b81010312610646575138612e88565b3d9150613318565b1561334357565b608460405162461bcd60e51b815260206004820152603060248201527f4465706f7369747320696e746f20526f636b657420506f6f6c2061726520637560448201527f7272656e746c792064697361626c6564000000000000000000000000000000006064820152fd5b602460206001600160a01b0360005460081c16604051928380927f21f8a7210000000000000000000000000000000000000000000000000000000082527f65dd923ddfc8d8ae6088f80077201d2403cbd565f0ba25e09841e2799ec90bb260048301525afa90811561261557600091613424575090565b90506020813d602011613450575b8161343f60209383612507565b810103126106465761284190612b19565b3d9150613432565b60206001600160a01b0360005460081c16916024604051809481937f21f8a72100000000000000000000000000000000000000000000000000000000835260048301525afa90811561261557600091613424575090565b6134ef9060405161036a816101c560208201947f636f6e74726163742e6164647265737300000000000000000000000000000000865260308301906126cf565b6001600160a01b038116156135015790565b606460405162461bcd60e51b815260206004820152601260248201527f436f6e7472616374206e6f7420666f756e6400000000000000000000000000006044820152fd5b90602460206001600160a01b0361356360405161298b604082612507565b16604051928380927ffd82e9dd0000000000000000000000000000000000000000000000000000000082527fa7c30d79bac38383b63cf527b2a68c8a7efff3ba22dfd5b81d98030643ef0fca60048301525afa90811561261557600091613606575b50806135df575b50816135d6575050565b612de49161496f565b91908183106135f35750612de4915061454b565b908261360091039261454b565b386135cc565b906020823d602011613630575b8161362060209383612507565b810103126102c6575051386135c5565b3d9150613613565b602460206001600160a01b0360005460081c16604051928380927fbd02d0f50000000000000000000000000000000000000000000000000000000082527f6465706f7369742e706f6f6c2e6e6f64652e62616c616e63650000000000000060048301525afa908115612615576000916125e6575090565b602460206001600160a01b0360005460081c16604051928380927fbd02d0f50000000000000000000000000000000000000000000000000000000082527fb869ecac5aab3eca31bf3f499f9eb526669f14aa1402bb5674c73cd5a5b2611f60048301525afa908115612615576000916125e6575090565b602460206001600160a01b0360005460081c16604051928380927fbd02d0f50000000000000000000000000000000000000000000000000000000082527f43d6a8fcdd5ecf01f71d0e1d9b20163adaa8fbb9e896e8263c967735d0ae5ce060048301525afa908115612615576000916125e6575090565b602460206001600160a01b0360005460081c16604051928380927fbd02d0f50000000000000000000000000000000000000000000000000000000082527fe854d579bb35988f8f3715377be8a57a13d9f9db42d0eaf95a3a8f39a96bca4460048301525afa908115612615576000916125e6575090565b60206001600160a01b0360005460081c16916024604051809481937fbd02d0f500000000000000000000000000000000000000000000000000000000835260048301525afa908115612615576000916125e6575090565b6000916001600160a01b03835460081c1691823b1561135d5790604484928360405195869485937fadb353dc000000000000000000000000000000000000000000000000000000008552600485015260248401525af180156102bb576138cf575050565b816138d991612507565b50565b60206001600160a01b0360005460081c16916024604051809481937f7ae1cfca00000000000000000000000000000000000000000000000000000000835260048301525afa90811561261557600091613933575090565b612841915060203d60201161081b5761080d8183612507565b90612de4916040516139a2816101c56020820194856bffffffffffffffffffffffff196034927f6d656761706f6f6c2e6574682e6d6174636865642e6e6f64652e616d6f756e74835260601b1660208201520190565b51902061386b565b9081602091031261064657517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681036106465790565b906000916001600160a01b036139fb604051611165604082612507565b1690604051613a74816101c56020820194856bffffffffffffffffffffffff196035927f6d656761706f6f6c2e6574682e70726f76696465642e6e6f64652e616d6f756e83527f7400000000000000000000000000000000000000000000000000000000000000602084015260601b1660218201520190565b519020916040517f6838444b000000000000000000000000000000000000000000000000000000008152836004820152602081602481865afa9081156107e857917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff613ae69281948891613b5e575b5016612736565b1691813b1561135d576040517f5ba5964900000000000000000000000000000000000000000000000000000000815260048101919091527bffffffffffffffffffffffffffffffffffffffffffffffffffffffff92909216602483015282908290604490829084905af180156102bb576138cf575050565b613b77915060203d6020116113895761137b8183612507565b38613adf565b613ba5577f3676a2bfaf1dbda572dffd9f1bf1596b6bda293af53a4f0eb0ecb236bf64075e90565b7f5a55531ca116b9495f14b748a940f79340b078cefcdd2db09ea1ce8b68bad15b90565b6000906001600160a01b03825460081c1690813b15610d625782916044839260405194859384927febb9d8c90000000000000000000000000000000000000000000000000000000084527f43d6a8fcdd5ecf01f71d0e1d9b20163adaa8fbb9e896e8263c967735d0ae5ce0600485015260248401525af180156102bb576138cf575050565b6000906001600160a01b03825460081c1690813b15610d625782916044839260405194859384927febb9d8c90000000000000000000000000000000000000000000000000000000084527f6465706f7369742e706f6f6c2e6e6f64652e62616c616e636500000000000000600485015260248401525af180156102bb576138cf575050565b6000916001600160a01b03835460081c1691823b1561135d5790604484928360405195869485937febb9d8c9000000000000000000000000000000000000000000000000000000008552600485015260248401525af180156102bb576138cf575050565b612de46fffffffffffffffffffffffffffffffff613d5361379d565b167fffffffffffffffffffffffffffffffff000000000000000000000000000000004360801b161761502c565b612de4613d8b61379d565b7fffffffffffffffffffffffffffffffff0000000000000000000000000000000016436fffffffffffffffffffffffffffffffff161761502c565b63ffffffff8111613dda5763ffffffff1690565b608460405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203360448201527f32206269747300000000000000000000000000000000000000000000000000006064820152fd5b91906000906001600160a01b03613e626040516103ec604082612507565b166040517f6ada7847000000000000000000000000000000000000000000000000000000008152602081600481855afa9081156108575790613eaa918591610909575061333c565b6001600160a01b03613ef2604051613ec3604082612507565b601581527f726f636b65744d656761706f6f6c466163746f7279000000000000000000000060208201526134af565b1694604051957f4e1ccaf10000000000000000000000000000000000000000000000000000000087526001600160a01b03821696876004820152602081602481855afa908115614362578691614343575b50156142ff576020602491604051928380927f74db6b880000000000000000000000000000000000000000000000000000000082528b60048301525afa9081156107e85785916142ba575b5060206001600160a01b03916004604051809481937f14a6bf0f000000000000000000000000000000000000000000000000000000008352165afa9081156107e8578591614288575b5061421e5760405161402d816101c56020820194856bffffffffffffffffffffffff19602f927f6e6f64652e6465706f7369742e6372656469742e62616c616e63650000000000835260601b16601b8201520190565b5190208461403a82613814565b106141da5760049161404e86602093613cd3565b61408d60405161405f604082612507565b601181527f726f636b65744e6f64654d616e61676572000000000000000000000000000000848201526134af565b50604051928380927f0de705b50000000000000000000000000000000000000000000000000000000082525afa9081156108fe5783916141a8575b506001600160a01b037f000000000000000000000000ae78736cd615f374d3085123a210448e74fc63931690813b1561135d576040517f94bf804d000000000000000000000000000000000000000000000000000000008152670de0b6b3a764000091860291909104850360048201526001600160a01b0392909216602483015282908290604490829084905af180156102bb57917f77982616940619ddbda4afe3675280fff7c605d31503336add3633fbea69d8ba9391604093614198575b50508151908152426020820152a2565b816141a291612507565b38614188565b90506020813d6020116141d2575b816141c360209383612507565b81010312610d625751386140c8565b3d91506141b6565b606460405162461bcd60e51b815260206004820152601f60248201527f416d6f756e7420657863656564732063726564697420617661696c61626c65006044820152fd5b608460405162461bcd60e51b815260206004820152602860248201527f43616e6e6f7420776974686472617720637265646974207768696c652064656260448201527f74206578697374730000000000000000000000000000000000000000000000006064820152fd5b90506020813d6020116142b2575b816142a360209383612507565b81010312611a24575138613fd7565b3d9150614296565b90506020813d6020116142f7575b816142d560209383612507565b81010312611a245760206142f06001600160a01b0392612b19565b9150613f8e565b3d91506142c8565b606460405162461bcd60e51b815260206004820152601960248201527f4d656761706f6f6c206d757374206265206465706c6f796564000000000000006044820152fd5b61435c915060203d60201161081b5761080d8183612507565b38613f43565b6040513d88823e3d90fd5b6143756150b1565b3481116144a0575b6143878134612736565b9060009080614424575b5090806143a3575b5050612de461527e565b6001600160a01b037f0000000000000000000000003bdc69c4e5e13e52a65f5583c23efb9636b469d616803b15610d625782906004604051809481937f98ea5fca0000000000000000000000000000000000000000000000000000000083525af180156102bb57156143995761441a828092612507565b6102c65780614399565b6001600160a01b037f000000000000000000000000ae78736cd615f374d3085123a210448e74fc639316803b15610d625782906004604051809481937f6c985a880000000000000000000000000000000000000000000000000000000083525af180156102bb5715614391578161449a91612507565b38614391565b503461437d565b604051906144b6606083612507565b602182527f6c000000000000000000000000000000000000000000000000000000000000006040837f726f636b657444414f50726f746f636f6c53657474696e67734d696e69706f6f60208201520152565b805182101561451c5760209160051b010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060046000926001600160a01b0361459960405161456a604082612507565b601381527f726f636b65744d696e69706f6f6c51756575650000000000000000000000000060208201526134af565b169060206001600160a01b036145b56145b06144a7565b6134af565b16604051948580927f3469f7b40000000000000000000000000000000000000000000000000000000082525afa9283156107e857859361493b575b50614602836145fd612548565b612c9b565b8015614933579160248284889586951161492b575b5060405197889384927f7e0e497b00000000000000000000000000000000000000000000000000000000845260048401525af1938415612298578194614858575b50835180614668575b5050509050565b8261467291612b96565b6001600160a01b037f0000000000000000000000003bdc69c4e5e13e52a65f5583c23efb9636b469d61690813b15610d625782916024839260405194859384927f3bed33ce00000000000000000000000000000000000000000000000000000000845260048401525af180156102bb578290614848575b8291505b8551821015614830576001600160a01b036147088388614508565b5116803b1561135d576040517fd0e30db0000000000000000000000000000000000000000000000000000000008152848160048189865af180156107e85790859161481b575b50506020600491604051928380927fd2ceebd10000000000000000000000000000000000000000000000000000000082525afa9081156108575784916147e7575b5061479c906001926126fa565b916001600160a01b036147af8289614508565b51167fa1811054b7d96716259cff0d366c2f6405951e0efe00c8db3e237cbf77fe7be960408051888152426020820152a201906146ed565b905060203d8111614814575b6147fd8183612507565b602082600092810103126102c6575051600161478f565b503d6147f3565b8161482591612507565b61135d57833861474e565b9250505061483f919250613c4e565b80388080614661565b61485191612507565b38816146e9565b9093503d8085833e61486a8183612507565b810190602081830312611a245780519067ffffffffffffffff821161135957019080601f83011215611a245781519167ffffffffffffffff83116148fe578260051b90604051936148be6020840186612507565b84526020808501928201019283116114c157602001905b8282106148e6575050509238614658565b602080916148f384612b19565b8152019101906148d5565b6024867f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b905038614617565b505050509050565b9092506020813d602011614967575b8161495760209383612507565b81010312611a24575191386145f0565b3d915061494a565b6001600160a01b03614988604051610faf604082612507565b166040517ffd82e9dd0000000000000000000000000000000000000000000000000000000081527f5a55531ca116b9495f14b748a940f79340b078cefcdd2db09ea1ce8b68bad15b6004820152602081602481855afa90811561261557600091614ffa575b506040517ffd82e9dd0000000000000000000000000000000000000000000000000000000081527f3676a2bfaf1dbda572dffd9f1bf1596b6bda293af53a4f0eb0ecb236bf64075e6004820152602081602481865afa90811561261557600091614fc8575b50906001600160a01b036020614a666136af565b966004604051809481937f1aff58eb000000000000000000000000000000000000000000000000000000008352165afa90811561261557600091614f96575b509293916000918293614ab6612548565b928496859886946001600160a01b037f0000000000000000000000003bdc69c4e5e13e52a65f5583c23efb9636b469d616905b858710614c62575b5050505050505050614b0290613c4e565b6001600160a01b0360005460081c1693843b15610646576000946044869260405197889384927fe2a4853a0000000000000000000000000000000000000000000000000000000084527fb869ecac5aab3eca31bf3f499f9eb526669f14aa1402bb5674c73cd5a5b2611f600485015260248401525af190811561261557612de494614b9292614c51575b50613bc9565b614b9a61379d565b9015614c38576fffffffffffffffffffffffffffffffff4316915b15614bfd57506fffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffff000000000000000000000000000000008143165b60801b1691161761502c565b7fffffffffffffffffffffffffffffffff000000000000000000000000000000006fffffffffffffffffffffffffffffffff9160801c614bf1565b6fffffffffffffffffffffffffffffffff811691614bb5565b6000614c5c91612507565b38614b8c565b9091929394969b9897959981159c8d809e614f8e575b614f82576001860180871161270757614c9287918d612c62565b1415809e81614f7a575b50614f71575b8d1580614f69575b614f60575b614cb88e613b7d565b90604051987f4fd8f054000000000000000000000000000000000000000000000000000000008a528260048b015260808a6024818a5afa998a156126155760009a614f40575b5063ffffffff60608b0151169166038d7ea4c6800083029280840466038d7ea4c68000149015171561270757828110614f3357863b1561064657604051907f3bed33ce000000000000000000000000000000000000000000000000000000008252836004830152600082602481838c5af190811561261557614d87928592614f22575b50612736565b996001600160a01b0381511663ffffffff602083015116813b15610646578491602460009260405194859384927f7685e80b00000000000000000000000000000000000000000000000000000000845260048401525af1801561261557614f11575b506001600160a01b038151167f21d4fea1e00248ceff22105d25fec21f17b7134ab4881761ab27ac2d4249fdee60408051868152426020820152a2604051937fdc5be997000000000000000000000000000000000000000000000000000000008552600485015260808460248160008c5af193841561261557604066038d7ea4c680009263ffffffff92600197614ef5575b5001511602019a019a019c600014614ec457507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01946001809a5b019596949392919096614ae9565b999a5094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01936001809b614eb6565b614f0c9060803d8111611a8757611a788183612507565b614e7b565b6000614f1c91612507565b38614de9565b6000614f2d91612507565b38614d81565b509a9b9e50505099614af1565b614f59919a5060803d8111611a8757611a788183612507565b9838614cfe565b60019d50614caf565b508615614caa565b60009d50614ca2565b905038614c9c565b50998698999c50614af1565b508615614c78565b906020823d602011614fc0575b81614fb060209383612507565b810103126102c657505138614aa5565b3d9150614fa3565b90506020813d602011614ff2575b81614fe360209383612507565b81010312610646575138614a52565b3d9150614fd6565b90506020813d602011615024575b8161501560209383612507565b810103126106465751386149ed565b3d9150615008565b6000906001600160a01b03825460081c1690813b15610d625782916044839260405194859384927fe2a4853a0000000000000000000000000000000000000000000000000000000084527fe854d579bb35988f8f3715377be8a57a13d9f9db42d0eaf95a3a8f39a96bca44600485015260248401525af180156102bb576138cf575050565b6001600160a01b036150f96040516150ca604082612507565b602081527f726f636b657444414f50726f746f636f6c53657474696e67734e6574776f726b60208201526134af565b16600460206001600160a01b03615145604051615117604082612507565b601581527f726f636b65744e6574776f726b42616c616e6365730000000000000000000000848201526134af565b1692604051928380927fe28767130000000000000000000000000000000000000000000000000000000082525afa9081156126155760009161524c575b50600460206001600160a01b037f000000000000000000000000ae78736cd615f374d3085123a210448e74fc6393163193604051928380927f964d042c0000000000000000000000000000000000000000000000000000000082525afa90811561261557600091615212575b50670de0b6b3a76400009161520291612b96565b0490808211612c25575050600090565b90506020813d602011615244575b8161522d60209383612507565b810103126106465751670de0b6b3a76400006151ee565b3d9150615220565b90506020813d602011615276575b8161526760209383612507565b81010312610646575138615182565b3d915061525a565b6001600160a01b036152976040516103ec604082612507565b166040517f47fa434a000000000000000000000000000000000000000000000000000000008152602081600481855afa9081156126155760009161567f575b50156138d957602460206001600160a01b036152f960405161298b604082612507565b16604051928380927ffd82e9dd0000000000000000000000000000000000000000000000000000000082527fa7c30d79bac38383b63cf527b2a68c8a7efff3ba22dfd5b81d98030643ef0fca60048301525afa9081156126155760009161564d575b50156155375761537260405161456a604082612507565b506001600160a01b036153866145b06144a7565b16604051907f3b474a65000000000000000000000000000000000000000000000000000000008252602082600481865afa91821561261557600092615502575b506020600491604051928380927f3469f7b40000000000000000000000000000000000000000000000000000000082525afa8015612615576000906154cf575b6004915060206154226154198334612c9b565b926145fd612548565b94604051938480927ff19b41060000000000000000000000000000000000000000000000000000000082525afa80156126155760009061549b575b61546792506126fa565b91808311615493575b5080821161548b575b50806154825750565b612de49061454b565b905038615479565b915038615470565b506020823d6020116154c7575b816154b560209383612507565b8101031261064657615467915161545d565b3d91506154a8565b6020823d6020116154fa575b816154e860209383612507565b810103126102c6575060049051615406565b3d91506154db565b90916020823d60201161552f575b8161551d60209383612507565b810103126102c65750519060206153c6565b3d9150615510565b604051907f3b474a65000000000000000000000000000000000000000000000000000000008252602082600481845afa91821561261557600092615619575b506040517ff19b4106000000000000000000000000000000000000000000000000000000008152602081600481855afa8015612615576000906155e5575b6155cb91506801bc16d674ec8000003404906126fa565b918083116155dd5750816135d6575050565b9150386135cc565b506020813d602011615611575b816155ff60209383612507565b81010312610646576155cb90516155b4565b3d91506155f2565b90916020823d602011615645575b8161563460209383612507565b810103126102c65750519038615576565b3d9150615627565b90506020813d602011615677575b8161566860209383612507565b8101031261064657513861535b565b3d915061565b565b615698915060203d60201161081b5761080d8183612507565b386152d656fea26469706673582212208dd5003687e3781407bc3a73ee56aad724c9a77056eaf616c7b60f77ef68cc5364736f6c634300081e0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000001d8f8f00cfa6758d7be78336684788fb0ee0fa46
-----Decoded View---------------
Arg [0] : _rocketStorageAddress (address): 0x1d8f8f00cfa6758d7bE78336684788Fb0ee0Fa46
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000001d8f8f00cfa6758d7be78336684788fb0ee0fa46
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.