-
Notifications
You must be signed in to change notification settings - Fork 195
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Vaults] Immutably fix the node operator in the basic StakingVault
#897
base: feat/vaults
Are you sure you want to change the base?
Changes from 19 commits
7e7edee
2de4da5
1bcd4fd
9030b5c
03a84a8
1395555
751c77e
17b88bf
a50851f
91d432e
212ec13
50b04f6
9faf18a
06340ca
20d7db8
1a843a9
7a7e622
e137105
cfc013b
5185b04
ce7ccb8
496e6f2
79653dd
bb43b2e
afcb7d3
1463ad3
732dbf4
6256c16
34261a9
bc86331
21425d0
7899756
8d7a6af
2f0ec60
d9888f0
c34ebe1
4897271
d0b1d4c
f7086b5
887fec3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,7 @@ | |
// See contracts/COMPILERS.md | ||
pragma solidity 0.8.25; | ||
|
||
import {MemUtils} from "../../common/lib/MemUtils.sol"; | ||
import {MemUtils} from "contracts/common/lib/MemUtils.sol"; | ||
|
||
interface IDepositContract { | ||
function get_deposit_root() external view returns (bytes32 rootHash); | ||
|
@@ -26,7 +26,7 @@ interface IDepositContract { | |
* | ||
* This contract will be refactored to support custom deposit amounts for MAX_EB. | ||
*/ | ||
contract VaultBeaconChainDepositor { | ||
contract BeaconChainDepositLogistics { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure if this makes the naming better, tbh |
||
uint256 internal constant PUBLIC_KEY_LENGTH = 48; | ||
uint256 internal constant SIGNATURE_LENGTH = 96; | ||
uint256 internal constant DEPOSIT_SIZE = 32 ether; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like we have 3 different role hierarchy: independent operator in vault, operatir in delegation and default_admin in delegation. But looks like it should be only two of them: |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -53,23 +53,15 @@ contract Delegation is Dashboard, IReportReceiver { | |
*/ | ||
bytes32 public constant STAKER_ROLE = keccak256("Vault.Delegation.StakerRole"); | ||
|
||
/** | ||
* @notice Role for the operator | ||
* Operator can: | ||
/** | ||
* @notice Role for the node operator | ||
* Node operator rewards claimer can: | ||
mymphe marked this conversation as resolved.
Show resolved
Hide resolved
|
||
* - claim the performance due | ||
* - vote on performance fee changes | ||
* - vote on ownership transfer | ||
* - set the Key Master role | ||
*/ | ||
bytes32 public constant OPERATOR_ROLE = keccak256("Vault.Delegation.OperatorRole"); | ||
|
||
/** | ||
* @notice Role for the key master. | ||
* Key master can: | ||
* - deposit validators to the beacon chain | ||
*/ | ||
bytes32 public constant KEY_MASTER_ROLE = keccak256("Vault.Delegation.KeyMasterRole"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It may be preliminary to get rid of this role. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why? Keymaster does not have any duties in the delegation contract, since they use the base vault for depositing validator keys. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It still can be a useful to have a role that can only deposit, but have no access to fees or role setup. |
||
|
||
/** | ||
* @notice Role for the token master. | ||
* Token master can: | ||
|
@@ -78,15 +70,6 @@ contract Delegation is Dashboard, IReportReceiver { | |
*/ | ||
bytes32 public constant TOKEN_MASTER_ROLE = keccak256("Vault.Delegation.TokenMasterRole"); | ||
|
||
/** | ||
* @notice Role for the Lido DAO. | ||
* This can be the Lido DAO agent, EasyTrack or any other DAO decision-making system. | ||
* Lido DAO can: | ||
* - set the operator role | ||
* - vote on ownership transfer | ||
*/ | ||
bytes32 public constant LIDO_DAO_ROLE = keccak256("Vault.Delegation.LidoDAORole"); | ||
|
||
// ==================== State Variables ==================== | ||
|
||
/// @notice The last report for which the performance due was claimed | ||
|
@@ -121,36 +104,16 @@ contract Delegation is Dashboard, IReportReceiver { | |
/** | ||
* @notice Initializes the contract with the default admin and `StakingVault` address. | ||
* Sets up roles and role administrators. | ||
* @param _defaultAdmin Address to be granted the `DEFAULT_ADMIN_ROLE`. | ||
* @param _stakingVault Address of the `StakingVault` contract. | ||
* @dev This function is called by the `VaultFactory` contract | ||
*/ | ||
function initialize(address _defaultAdmin, address _stakingVault) external override { | ||
_initialize(_defaultAdmin, _stakingVault); | ||
|
||
/** | ||
* Granting `LIDO_DAO_ROLE` to the default admin is needed to set the initial Lido DAO address | ||
* in the `createVault` function in the vault factory, so that we don't have to pass it | ||
* to this initialize function and break the inherited function signature. | ||
* This role will be revoked in the `createVault` function in the vault factory and | ||
* will only remain on the Lido DAO address | ||
*/ | ||
_grantRole(LIDO_DAO_ROLE, _defaultAdmin); | ||
|
||
/** | ||
* Only Lido DAO can assign the Lido DAO role. | ||
*/ | ||
_setRoleAdmin(LIDO_DAO_ROLE, LIDO_DAO_ROLE); | ||
|
||
/** | ||
* The node operator in the vault must be approved by Lido DAO. | ||
* The vault owner (`DEFAULT_ADMIN_ROLE`) cannot change the node operator. | ||
*/ | ||
_setRoleAdmin(OPERATOR_ROLE, LIDO_DAO_ROLE); | ||
|
||
/** | ||
* The operator role can change the key master role. | ||
*/ | ||
_setRoleAdmin(KEY_MASTER_ROLE, OPERATOR_ROLE); | ||
function initialize(address _stakingVault) external override { | ||
_initialize(_stakingVault); | ||
|
||
// `OPERATOR_ROLE` is set to `msg.sender` to allow the `VaultFactory` to set the initial operator fee | ||
// the role will be revoked from `VaultFactory` | ||
_grantRole(OPERATOR_ROLE, msg.sender); | ||
_setRoleAdmin(OPERATOR_ROLE, OPERATOR_ROLE); | ||
} | ||
|
||
// ==================== View Functions ==================== | ||
|
@@ -163,13 +126,13 @@ contract Delegation is Dashboard, IReportReceiver { | |
function withdrawable() public view returns (uint256) { | ||
// Question: shouldn't we reserve both locked + dues, not max(locked, dues)? | ||
uint256 reserved = Math256.max(stakingVault.locked(), managementDue + performanceDue()); | ||
uint256 value = stakingVault.valuation(); | ||
uint256 valuation = stakingVault.valuation(); | ||
|
||
if (reserved > value) { | ||
if (reserved > valuation) { | ||
return 0; | ||
} | ||
|
||
return value - reserved; | ||
return valuation - reserved; | ||
} | ||
|
||
/** | ||
|
@@ -194,10 +157,9 @@ contract Delegation is Dashboard, IReportReceiver { | |
* @return An array of role identifiers. | ||
*/ | ||
function ownershipTransferCommittee() public pure returns (bytes32[] memory) { | ||
bytes32[] memory roles = new bytes32[](3); | ||
bytes32[] memory roles = new bytes32[](2); | ||
roles[0] = MANAGER_ROLE; | ||
roles[1] = OPERATOR_ROLE; | ||
roles[2] = LIDO_DAO_ROLE; | ||
return roles; | ||
} | ||
|
||
|
@@ -240,7 +202,7 @@ contract Delegation is Dashboard, IReportReceiver { | |
*/ | ||
function claimManagementDue(address _recipient, bool _liquid) external onlyRole(MANAGER_ROLE) { | ||
if (_recipient == address(0)) revert ZeroArgument("_recipient"); | ||
if (!stakingVault.isHealthy()) revert VaultNotHealthy(); | ||
if (!stakingVault.isBalanced()) revert VaultUnbalanced(); | ||
tamtamchik marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
uint256 due = managementDue; | ||
|
||
|
@@ -298,20 +260,6 @@ contract Delegation is Dashboard, IReportReceiver { | |
_withdraw(_recipient, _ether); | ||
} | ||
|
||
/** | ||
* @notice Deposits validators to the beacon chain. | ||
* @param _numberOfDeposits Number of validator deposits. | ||
* @param _pubkeys Concatenated public keys of the validators. | ||
* @param _signatures Concatenated signatures of the validators. | ||
*/ | ||
function depositToBeaconChain( | ||
uint256 _numberOfDeposits, | ||
bytes calldata _pubkeys, | ||
bytes calldata _signatures | ||
) external override onlyRole(KEY_MASTER_ROLE) { | ||
_depositToBeaconChain(_numberOfDeposits, _pubkeys, _signatures); | ||
} | ||
|
||
/** | ||
* @notice Claims the performance fee due. | ||
* @param _recipient Address of the recipient. | ||
|
@@ -491,8 +439,8 @@ contract Delegation is Dashboard, IReportReceiver { | |
/// @param requested The amount requested to withdraw. | ||
error InsufficientUnlockedAmount(uint256 unlocked, uint256 requested); | ||
|
||
/// @notice Error when the vault is not healthy. | ||
error VaultNotHealthy(); | ||
/// @notice Error when the vault is not balanced. | ||
error VaultUnbalanced(); | ||
tamtamchik marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
/// @notice Hook can only be called by the staking vault. | ||
error OnlyStVaultCanCallOnReportHook(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure what the process is here, do we need to import our contracts always under "contracts/" namespace or use a relative path?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think imports relative to root are much more readable. You can clearly see where the file is imported from