Contract Design & Upgradability
Architecture
The Rocket Pool network contracts are built with upgradability in mind, using a hub-and-spoke architecture. The central hub of the network is the RocketStorage
contract, which is responsible for storing the state of the entire network. This is implemented through the use of maps for key-value storage, and getter and setter methods for reading and writing values for a key.
The RocketStorage
contract also stores the addresses of all other network contracts (keyed by name), and restricts data modification to those contracts only. Using this architecture, the network can be upgraded by deploying new versions of an existing contract, and updating its address in storage. This gives Rocket Pool the flexibility required to fix bugs or implement new features to improve the network.
Interacting With Rocket Pool
To begin interacting with the Rocket Pool network, first create an instance of the RocketStorage
contract using its interface:
import "RocketStorageInterface.sol";
contract Example {
RocketStorageInterface rocketStorage = RocketStorageInterface(0);
constructor(address _rocketStorageAddress) {
rocketStorage = RocketStorageInterface(_rocketStorageAddress);
}
}
The above constructor should be called with the address of the RocketStorage
contract on the appropriate network.
Because of Rocket Pool's architecture, the addresses of other contracts should not be used directly, but retrieved from the blockchain before use. Network upgrades may have occurred since the previous interaction, resulting in outdated addresses.
Other contract instances can be created using the appropriate interface taken from the Rocket Pool repository, e.g.:
import "RocketStorageInterface.sol";
import "RocketDepositPoolInterface.sol";
contract Example {
RocketStorageInterface rocketStorage = RocketStorageInterface(0);
constructor(address _rocketStorageAddress) {
rocketStorage = RocketStorageInterface(_rocketStorageAddress);
}
exampleMethod() public {
address rocketDepositPoolAddress = rocketStorage.getAddress(keccak256(abi.encodePacked("contract.address", "rocketDepositPool")));
RocketDepositPoolInterface rocketDepositPool = RocketDepositPoolInterface(rocketDepositPoolAddress);
...
}
}
The Rocket Pool contracts, as defined in RocketStorage
, are:
rocketRole
- Handles assignment of privileged admin roles (internal)rocketVault
- Stores ETH held by network contracts (internal, not upgradeable)rocketUpgrade
- Provides upgrade functionality for the network (internal)rocketDepositPool
- Accepts user-deposited ETH and handles assignment to minipoolsrocketMinipoolFactory
- Creates minipool contract instances (internal)rocketMinipoolManager
- Creates & manages all minipools in the networkrocketMinipoolQueue
- Organises minipools into a queue for ETH assignmentrocketMinipoolStatus
- Handles minipool status updates from watchtower nodesrocketNetworkBalances
- Handles network balance updates from watchtower nodesrocketNetworkFees
- Calculates node commission rates based on network node demandrocketNetworkWithdrawal
- Handles processing of beacon chain validator withdrawalsrocketNodeDeposit
- Handles node deposits for minipool creationrocketNodeManager
- Registers & manages all nodes in the networkrocketDAOProtocolSettingsDeposit
- Provides network settings relating to depositsrocketDAOProtocolSettingsMinipool
- Provides network settings relating to minipoolsrocketDAOProtocolSettingsNetwork
- Provides miscellaneous network settingsrocketDAOProtocolSettingsNode
- Provides network settings relating to nodesrocketTokenRETH
- The rETH token contract (not upgradeable)addressQueueStorage
- A utility contract (internal)addressSetStorage
- A utility contract (internal)
Contracts marked as "internal" do not provide methods which are accessible to the general public, and so are generally not useful for extension. For information on specific contract methods, consult their interfaces in the Rocket Pool repository.