creation_sourcecode: {{
    "language": "Solidity",
    "sources": {
      "contracts/interface/RocketStorageInterface.sol": {
        "content": "/**\r\n  *       .\r\n  *      / \\\r\n  *     |.'.|\r\n  *     |'.'|\r\n  *   ,'|   |`.\r\n  *  |,-'-|-'-.|\r\n  *   __|_| |         _        _      _____           _\r\n  *  | ___ \\|        | |      | |    | ___ \\         | |\r\n  *  | |_/ /|__   ___| | _____| |_   | |_/ /__   ___ | |\r\n  *  |    // _ \\ / __| |/ / _ \\ __|  |  __/ _ \\ / _ \\| |\r\n  *  | |\\ \\ (_) | (__|   <  __/ |_   | | | (_) | (_) | |\r\n  *  \\_| \\_\\___/ \\___|_|\\_\\___|\\__|  \\_|  \\___/ \\___/|_|\r\n  * +---------------------------------------------------+\r\n  * |  DECENTRALISED STAKING PROTOCOL FOR ETHEREUM 2.0  |\r\n  * +---------------------------------------------------+\r\n  *\r\n  *  Rocket Pool is a first-of-its-kind ETH2 Proof of Stake protocol, designed to be community owned,\r\n  *  decentralised, trustless and compatible with staking in Ethereum 2.0.\r\n  *\r\n  *  For more information about Rocket Pool, visit https://rocketpool.net\r\n  *\r\n  *  Authors: David Rugendyke, Jake Pospischil, Kane Wallmann, Darren Langley, Joe Clapis, Nick Doherty\r\n  *\r\n  */\r\n\r\npragma solidity >0.5.0 <0.9.0;\n\n// SPDX-License-Identifier: GPL-3.0-only\n\ninterface RocketStorageInterface {\n\n    // Deploy status\n    function getDeployedStatus() external view returns (bool);\n\n    // Guardian\n    function getGuardian() external view returns(address);\n    function setGuardian(address _newAddress) external;\n    function confirmGuardian() external;\n\n    // Getters\n    function getAddress(bytes32 _key) external view returns (address);\n    function getUint(bytes32 _key) external view returns (uint);\n    function getString(bytes32 _key) external view returns (string memory);\n    function getBytes(bytes32 _key) external view returns (bytes memory);\n    function getBool(bytes32 _key) external view returns (bool);\n    function getInt(bytes32 _key) external view returns (int);\n    function getBytes32(bytes32 _key) external view returns (bytes32);\n\n    // Setters\n    function setAddress(bytes32 _key, address _value) external;\n    function setUint(bytes32 _key, uint _value) external;\n    function setString(bytes32 _key, string calldata _value) external;\n    function setBytes(bytes32 _key, bytes calldata _value) external;\n    function setBool(bytes32 _key, bool _value) external;\n    function setInt(bytes32 _key, int _value) external;\n    function setBytes32(bytes32 _key, bytes32 _value) external;\n\n    // Deleters\n    function deleteAddress(bytes32 _key) external;\n    function deleteUint(bytes32 _key) external;\n    function deleteString(bytes32 _key) external;\n    function deleteBytes(bytes32 _key) external;\n    function deleteBool(bytes32 _key) external;\n    function deleteInt(bytes32 _key) external;\n    function deleteBytes32(bytes32 _key) external;\n\n    // Arithmetic\n    function addUint(bytes32 _key, uint256 _amount) external;\n    function subUint(bytes32 _key, uint256 _amount) external;\n\n    // Protected storage\n    function getNodeWithdrawalAddress(address _nodeAddress) external view returns (address);\n    function getNodePendingWithdrawalAddress(address _nodeAddress) external view returns (address);\n    function setWithdrawalAddress(address _nodeAddress, address _newWithdrawalAddress, bool _confirm) external;\n    function confirmWithdrawalAddress(address _nodeAddress) external;\n}\n"
      },
      "contracts/types/MinipoolDeposit.sol": {
        "content": "/**\r\n  *       .\r\n  *      / \\\r\n  *     |.'.|\r\n  *     |'.'|\r\n  *   ,'|   |`.\r\n  *  |,-'-|-'-.|\r\n  *   __|_| |         _        _      _____           _\r\n  *  | ___ \\|        | |      | |    | ___ \\         | |\r\n  *  | |_/ /|__   ___| | _____| |_   | |_/ /__   ___ | |\r\n  *  |    // _ \\ / __| |/ / _ \\ __|  |  __/ _ \\ / _ \\| |\r\n  *  | |\\ \\ (_) | (__|   <  __/ |_   | | | (_) | (_) | |\r\n  *  \\_| \\_\\___/ \\___|_|\\_\\___|\\__|  \\_|  \\___/ \\___/|_|\r\n  * +---------------------------------------------------+\r\n  * |  DECENTRALISED STAKING PROTOCOL FOR ETHEREUM 2.0  |\r\n  * +---------------------------------------------------+\r\n  *\r\n  *  Rocket Pool is a first-of-its-kind ETH2 Proof of Stake protocol, designed to be community owned,\r\n  *  decentralised, trustless and compatible with staking in Ethereum 2.0.\r\n  *\r\n  *  For more information about Rocket Pool, visit https://rocketpool.net\r\n  *\r\n  *  Authors: David Rugendyke, Jake Pospischil, Kane Wallmann, Darren Langley, Joe Clapis, Nick Doherty\r\n  *\r\n  */\r\n\r\npragma solidity 0.7.6;\n\n// SPDX-License-Identifier: GPL-3.0-only\n\n// Represents the type of deposits required by a minipool\n\nenum MinipoolDeposit {\n    None,       // Marks an invalid deposit type\n    Full,       // The minipool requires 32 ETH from the node operator, 16 ETH of which will be refinanced from user deposits\n    Half,       // The minipool required 16 ETH from the node operator to be matched with 16 ETH from user deposits\n    Empty,      // The minipool requires 0 ETH from the node operator to be matched with 32 ETH from user deposits (trusted nodes only)\n    Variable    // Indicates this minipool is of the new generation that supports a variable deposit amount\n}\n"
      },
      "contracts/types/MinipoolStatus.sol": {
        "content": "/**\r\n  *       .\r\n  *      / \\\r\n  *     |.'.|\r\n  *     |'.'|\r\n  *   ,'|   |`.\r\n  *  |,-'-|-'-.|\r\n  *   __|_| |         _        _      _____           _\r\n  *  | ___ \\|        | |      | |    | ___ \\         | |\r\n  *  | |_/ /|__   ___| | _____| |_   | |_/ /__   ___ | |\r\n  *  |    // _ \\ / __| |/ / _ \\ __|  |  __/ _ \\ / _ \\| |\r\n  *  | |\\ \\ (_) | (__|   <  __/ |_   | | | (_) | (_) | |\r\n  *  \\_| \\_\\___/ \\___|_|\\_\\___|\\__|  \\_|  \\___/ \\___/|_|\r\n  * +---------------------------------------------------+\r\n  * |  DECENTRALISED STAKING PROTOCOL FOR ETHEREUM 2.0  |\r\n  * +---------------------------------------------------+\r\n  *\r\n  *  Rocket Pool is a first-of-its-kind ETH2 Proof of Stake protocol, designed to be community owned,\r\n  *  decentralised, trustless and compatible with staking in Ethereum 2.0.\r\n  *\r\n  *  For more information about Rocket Pool, visit https://rocketpool.net\r\n  *\r\n  *  Authors: David Rugendyke, Jake Pospischil, Kane Wallmann, Darren Langley, Joe Clapis, Nick Doherty\r\n  *\r\n  */\r\n\r\npragma solidity 0.7.6;\n\n// SPDX-License-Identifier: GPL-3.0-only\n\n// Represents a minipool's status within the network\n\nenum MinipoolStatus {\n    Initialised,    // The minipool has been initialised and is awaiting a deposit of user ETH\n    Prelaunch,      // The minipool has enough ETH to begin staking and is awaiting launch by the node operator\n    Staking,        // The minipool is currently staking\n    Withdrawable,   // NO LONGER USED\n    Dissolved       // The minipool has been dissolved and its user deposited ETH has been returned to the deposit pool\n}\n"
      },
      "contracts/contract/minipool/RocketMinipoolStorageLayout.sol": {
        "content": "/**\r\n  *       .\r\n  *      / \\\r\n  *     |.'.|\r\n  *     |'.'|\r\n  *   ,'|   |`.\r\n  *  |,-'-|-'-.|\r\n  *   __|_| |         _        _      _____           _\r\n  *  | ___ \\|        | |      | |    | ___ \\         | |\r\n  *  | |_/ /|__   ___| | _____| |_   | |_/ /__   ___ | |\r\n  *  |    // _ \\ / __| |/ / _ \\ __|  |  __/ _ \\ / _ \\| |\r\n  *  | |\\ \\ (_) | (__|   <  __/ |_   | | | (_) | (_) | |\r\n  *  \\_| \\_\\___/ \\___|_|\\_\\___|\\__|  \\_|  \\___/ \\___/|_|\r\n  * +---------------------------------------------------+\r\n  * |  DECENTRALISED STAKING PROTOCOL FOR ETHEREUM 2.0  |\r\n  * +---------------------------------------------------+\r\n  *\r\n  *  Rocket Pool is a first-of-its-kind ETH2 Proof of Stake protocol, designed to be community owned,\r\n  *  decentralised, trustless and compatible with staking in Ethereum 2.0.\r\n  *\r\n  *  For more information about Rocket Pool, visit https://rocketpool.net\r\n  *\r\n  *  Authors: David Rugendyke, Jake Pospischil, Kane Wallmann, Darren Langley, Joe Clapis, Nick Doherty\r\n  *\r\n  */\r\n\r\npragma solidity 0.7.6;\n\n// SPDX-License-Identifier: GPL-3.0-only\n\nimport \"../../interface/RocketStorageInterface.sol\";\nimport \"../../types/MinipoolDeposit.sol\";\nimport \"../../types/MinipoolStatus.sol\";\n\n// The RocketMinipool contract storage layout, shared by RocketMinipoolDelegate\n\n// ******************************************************\n// Note: This contract MUST NOT BE UPDATED after launch.\n// All deployed minipool contracts must maintain a\n// Consistent storage layout with RocketMinipoolDelegate.\n// ******************************************************\n\nabstract contract RocketMinipoolStorageLayout {\n    // Storage state enum\n    enum StorageState {\n        Undefined,\n        Uninitialised,\n        Initialised\n    }\n\n\t// Main Rocket Pool storage contract\n    RocketStorageInterface internal rocketStorage = RocketStorageInterface(0);\n\n    // Status\n    MinipoolStatus internal status;\n    uint256 internal statusBlock;\n    uint256 internal statusTime;\n    uint256 internal withdrawalBlock;\n\n    // Deposit type\n    MinipoolDeposit internal depositType;\n\n    // Node details\n    address internal nodeAddress;\n    uint256 internal nodeFee;\n    uint256 internal nodeDepositBalance;\n    bool internal nodeDepositAssigned;          // NO LONGER IN USE\n    uint256 internal nodeRefundBalance;\n    uint256 internal nodeSlashBalance;\n\n    // User deposit details\n    uint256 internal userDepositBalanceLegacy;\n    uint256 internal userDepositAssignedTime;\n\n    // Upgrade options\n    bool internal useLatestDelegate = false;\n    address internal rocketMinipoolDelegate;\n    address internal rocketMinipoolDelegatePrev;\n\n    // Local copy of RETH address\n    address internal rocketTokenRETH;\n\n    // Local copy of penalty contract\n    address internal rocketMinipoolPenalty;\n\n    // Used to prevent direct access to delegate and prevent calling initialise more than once\n    StorageState internal storageState = StorageState.Undefined;\n\n    // Whether node operator has finalised the pool\n    bool internal finalised;\n\n    // Trusted member scrub votes\n    mapping(address => bool) internal memberScrubVotes;\n    uint256 internal totalScrubVotes;\n\n    // Variable minipool\n    uint256 internal preLaunchValue;\n    uint256 internal userDepositBalance;\n\n    // Vacant minipool\n    bool internal vacant;\n    uint256 internal preMigrationBalance;\n\n    // User distribution\n    bool internal userDistributed;\n    uint256 internal userDistributeTime;\n}\n"
      },
      "contracts/interface/minipool/RocketMinipoolBaseInterface.sol": {
        "content": "/**\r\n  *       .\r\n  *      / \\\r\n  *     |.'.|\r\n  *     |'.'|\r\n  *   ,'|   |`.\r\n  *  |,-'-|-'-.|\r\n  *   __|_| |         _        _      _____           _\r\n  *  | ___ \\|        | |      | |    | ___ \\         | |\r\n  *  | |_/ /|__   ___| | _____| |_   | |_/ /__   ___ | |\r\n  *  |    // _ \\ / __| |/ / _ \\ __|  |  __/ _ \\ / _ \\| |\r\n  *  | |\\ \\ (_) | (__|   <  __/ |_   | | | (_) | (_) | |\r\n  *  \\_| \\_\\___/ \\___|_|\\_\\___|\\__|  \\_|  \\___/ \\___/|_|\r\n  * +---------------------------------------------------+\r\n  * |  DECENTRALISED STAKING PROTOCOL FOR ETHEREUM 2.0  |\r\n  * +---------------------------------------------------+\r\n  *\r\n  *  Rocket Pool is a first-of-its-kind ETH2 Proof of Stake protocol, designed to be community owned,\r\n  *  decentralised, trustless and compatible with staking in Ethereum 2.0.\r\n  *\r\n  *  For more information about Rocket Pool, visit https://rocketpool.net\r\n  *\r\n  *  Authors: David Rugendyke, Jake Pospischil, Kane Wallmann, Darren Langley, Joe Clapis, Nick Doherty\r\n  *\r\n  */\r\n\r\npragma solidity >0.5.0 <0.9.0;\n\n// SPDX-License-Identifier: GPL-3.0-only\n\ninterface RocketMinipoolBaseInterface {\n    function initialise(address _rocketStorage, address _nodeAddress) external;\n    function delegateUpgrade() external;\n    function delegateRollback() external;\n    function setUseLatestDelegate(bool _setting) external;\n    function getUseLatestDelegate() external view returns (bool);\n    function getDelegate() external view returns (address);\n    function getPreviousDelegate() external view returns (address);\n    function getEffectiveDelegate() external view returns (address);\n}\n"
      },
      "contracts/contract/minipool/RocketMinipoolBase.sol": {
        "content": "/**\r\n  *       .\r\n  *      / \\\r\n  *     |.'.|\r\n  *     |'.'|\r\n  *   ,'|   |`.\r\n  *  |,-'-|-'-.|\r\n  *   __|_| |         _        _      _____           _\r\n  *  | ___ \\|        | |      | |    | ___ \\         | |\r\n  *  | |_/ /|__   ___| | _____| |_   | |_/ /__   ___ | |\r\n  *  |    // _ \\ / __| |/ / _ \\ __|  |  __/ _ \\ / _ \\| |\r\n  *  | |\\ \\ (_) | (__|   <  __/ |_   | | | (_) | (_) | |\r\n  *  \\_| \\_\\___/ \\___|_|\\_\\___|\\__|  \\_|  \\___/ \\___/|_|\r\n  * +---------------------------------------------------+\r\n  * |  DECENTRALISED STAKING PROTOCOL FOR ETHEREUM 2.0  |\r\n  * +---------------------------------------------------+\r\n  *\r\n  *  Rocket Pool is a first-of-its-kind ETH2 Proof of Stake protocol, designed to be community owned,\r\n  *  decentralised, trustless and compatible with staking in Ethereum 2.0.\r\n  *\r\n  *  For more information about Rocket Pool, visit https://rocketpool.net\r\n  *\r\n  *  Authors: David Rugendyke, Jake Pospischil, Kane Wallmann, Darren Langley, Joe Clapis, Nick Doherty\r\n  *\r\n  */\r\n\r\n// SPDX-License-Identifier: GPL-3.0-only\npragma solidity 0.7.6;\n\nimport \"./RocketMinipoolStorageLayout.sol\";\nimport \"../../interface/RocketStorageInterface.sol\";\nimport \"../../interface/minipool/RocketMinipoolBaseInterface.sol\";\n\n/// @notice Contains the initialisation and delegate upgrade logic for minipools\ncontract RocketMinipoolBase is RocketMinipoolBaseInterface, RocketMinipoolStorageLayout {\n\n    // Events\n    event EtherReceived(address indexed from, uint256 amount, uint256 time);\n    event DelegateUpgraded(address oldDelegate, address newDelegate, uint256 time);\n    event DelegateRolledBack(address oldDelegate, address newDelegate, uint256 time);\n\n    // Store a reference to the address of RocketMinipoolBase itself to prevent direct calls to this contract\n    address immutable self;\n\n    constructor () {\n        self = address(this);\n    }\n\n    /// @dev Prevent direct calls to this contract\n    modifier notSelf() {\n        require(address(this) != self);\n        _;\n    }\n\n    /// @dev Only allow access from the owning node address\n    modifier onlyMinipoolOwner() {\n        // Only the node operator can upgrade\n        address withdrawalAddress = rocketStorage.getNodeWithdrawalAddress(nodeAddress);\n        require(msg.sender == nodeAddress || msg.sender == withdrawalAddress, \"Only the node operator can access this method\");\n        _;\n    }\n\n    /// @notice Sets up starting delegate contract and then delegates initialisation to it\n    function initialise(address _rocketStorage, address _nodeAddress) external override notSelf {\n        // Check input\n        require(_nodeAddress != address(0), \"Invalid node address\");\n        require(storageState == StorageState.Undefined, \"Already initialised\");\n        // Set storage state to uninitialised\n        storageState = StorageState.Uninitialised;\n        // Set rocketStorage\n        rocketStorage = RocketStorageInterface(_rocketStorage);\n        // Set the current delegate\n        address delegateAddress = getContractAddress(\"rocketMinipoolDelegate\");\n        rocketMinipoolDelegate = delegateAddress;\n        // Check for contract existence\n        require(contractExists(delegateAddress), \"Delegate contract does not exist\");\n        // Call initialise on delegate\n        (bool success, bytes memory data) = delegateAddress.delegatecall(abi.encodeWithSignature('initialise(address)', _nodeAddress));\n        if (!success) { revert(getRevertMessage(data)); }\n    }\n\n    /// @notice Receive an ETH deposit\n    receive() external payable notSelf {\n        // Emit ether received event\n        emit EtherReceived(msg.sender, msg.value, block.timestamp);\n    }\n\n    /// @notice Upgrade this minipool to the latest network delegate contract\n    function delegateUpgrade() external override onlyMinipoolOwner notSelf {\n        // Set previous address\n        rocketMinipoolDelegatePrev = rocketMinipoolDelegate;\n        // Set new delegate\n        rocketMinipoolDelegate = getContractAddress(\"rocketMinipoolDelegate\");\n        // Verify\n        require(rocketMinipoolDelegate != rocketMinipoolDelegatePrev, \"New delegate is the same as the existing one\");\n        // Log event\n        emit DelegateUpgraded(rocketMinipoolDelegatePrev, rocketMinipoolDelegate, block.timestamp);\n    }\n\n    /// @notice Rollback to previous delegate contract\n    function delegateRollback() external override onlyMinipoolOwner notSelf {\n        // Make sure they have upgraded before\n        require(rocketMinipoolDelegatePrev != address(0x0), \"Previous delegate contract is not set\");\n        // Store original\n        address originalDelegate = rocketMinipoolDelegate;\n        // Update delegate to previous and zero out previous\n        rocketMinipoolDelegate = rocketMinipoolDelegatePrev;\n        rocketMinipoolDelegatePrev = address(0x0);\n        // Log event\n        emit DelegateRolledBack(originalDelegate, rocketMinipoolDelegate, block.timestamp);\n    }\n\n    /// @notice Sets the flag to automatically use the latest delegate contract or not\n    /// @param _setting If true, will always use the latest delegate contract\n    function setUseLatestDelegate(bool _setting) external override onlyMinipoolOwner notSelf {\n        useLatestDelegate = _setting;\n    }\n\n    /// @notice Returns true if this minipool always uses the latest delegate contract\n    function getUseLatestDelegate() external override view returns (bool) {\n        return useLatestDelegate;\n    }\n\n    /// @notice Returns the address of the minipool's stored delegate\n    function getDelegate() external override view returns (address) {\n        return rocketMinipoolDelegate;\n    }\n\n    /// @notice Returns the address of the minipool's previous delegate (or address(0) if not set)\n    function getPreviousDelegate() external override view returns (address) {\n        return rocketMinipoolDelegatePrev;\n    }\n\n    /// @notice Returns the delegate which will be used when calling this minipool taking into account useLatestDelegate setting\n    function getEffectiveDelegate() external override view returns (address) {\n        return useLatestDelegate ? getContractAddress(\"rocketMinipoolDelegate\") : rocketMinipoolDelegate;\n    }\n\n    /// @notice Delegates all calls to minipool delegate contract (or latest if flag is set)\n    fallback(bytes calldata _input) external payable notSelf returns (bytes memory) {\n        // If useLatestDelegate is set, use the latest delegate contract\n        address delegateContract = useLatestDelegate ? getContractAddress(\"rocketMinipoolDelegate\") : rocketMinipoolDelegate;\n        // Check for contract existence\n        require(contractExists(delegateContract), \"Delegate contract does not exist\");\n        // Execute delegatecall\n        (bool success, bytes memory data) = delegateContract.delegatecall(_input);\n        if (!success) { revert(getRevertMessage(data)); }\n        return data;\n    }\n\n    /// @dev Get the address of a Rocket Pool network contract\n    function getContractAddress(string memory _contractName) private view returns (address) {\n        address contractAddress = rocketStorage.getAddress(keccak256(abi.encodePacked(\"contract.address\", _contractName)));\n        require(contractAddress != address(0x0), \"Contract not found\");\n        return contractAddress;\n    }\n\n    /// @dev Get a revert message from delegatecall return data\n    function getRevertMessage(bytes memory _returnData) private pure returns (string memory) {\n        if (_returnData.length < 68) { return \"Transaction reverted silently\"; }\n        assembly {\n            _returnData := add(_returnData, 0x04)\n        }\n        return abi.decode(_returnData, (string));\n    }\n\n    /// @dev Returns true if contract exists at _contractAddress (if called during that contract's construction it will return a false negative)\n    function contractExists(address _contractAddress) private view returns (bool) {\n        uint32 codeSize;\n        assembly {\n            codeSize := extcodesize(_contractAddress)\n        }\n        return codeSize > 0;\n    }\n}\n"
      }
    },
    "settings": {
      "optimizer": {
        "enabled": true,
        "runs": 15000
      },
      "outputSelection": {
        "*": {
          "*": [
            "evm.bytecode",
            "evm.deployedBytecode",
            "devdoc",
            "userdoc",
            "metadata",
            "abi"
          ]
        }
      }
    }
  }}