Skip to content

Commit

Permalink
fix: review (part 1)
Browse files Browse the repository at this point in the history
  • Loading branch information
vgorkavenko committed Dec 5, 2023
1 parent 87c4741 commit c77fac2
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 166 deletions.
65 changes: 41 additions & 24 deletions src/CSAccounting.sol
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ contract CSAccountingBase {
uint256 proposedBlockNumber,
uint256 stolenAmount
);
event BondLockCompensated(uint256 indexed nodeOperatorId, uint256 amount);
event BondLockReleased(uint256 indexed nodeOperatorId, uint256 amount);

error NotOwnerToClaim(address msgSender, address owner);
error InvalidSender();
Expand All @@ -79,6 +81,8 @@ contract CSAccounting is
keccak256("INSTANT_PENALIZE_BOND_ROLE"); // 0x9909cf24c2d3bafa8c229558d86a1b726ba57c3ef6350848dcf434a4181b56c7
bytes32 public constant EL_REWARDS_STEALING_PENALTY_INIT_ROLE =
keccak256("EL_REWARDS_STEALING_PENALTY_INIT_ROLE"); // 0xcc2e7ce7be452f766dd24d55d87a3d42901c31ffa5b600cd1dff475abec91c1f
bytes32 public constant EL_REWARDS_STEALING_PENALTY_RELEASE_ROLE =
keccak256("EL_REWARDS_STEALING_PENALTY_RELEASE_ROLE"); // 0x8d78671045c549f09e0cf6e7e9856c36698f72f93962abf8e1955dc595a592ee
bytes32 public constant EL_REWARDS_STEALING_PENALTY_SETTLE_ROLE =
keccak256("EL_REWARDS_STEALING_PENALTY_SETTLE_ROLE"); // 0xdf6226649a1ca132f86d419e46892001284368a8f7445b5eb0d3fadf91329fe6
bytes32 public constant SET_BOND_CURVE_ROLE =
Expand All @@ -100,8 +104,8 @@ contract CSAccounting is
/// @param lidoLocator lido locator contract address
/// @param wstETH wstETH contract address
/// @param communityStakingModule community staking module contract address
/// @param bondLockRetentionPeriod retention period for blocked bond in seconds
/// @param bondLockManagementPeriod management period for blocked bond in seconds
/// @param bondLockRetentionPeriod retention period for locked bond in seconds
/// @param bondLockManagementPeriod management period for locked bond in seconds
constructor(
uint256[] memory bondCurve,
address admin,
Expand Down Expand Up @@ -135,7 +139,7 @@ contract CSAccounting is
FEE_DISTRIBUTOR = fdAddress;
}

function setBlockedBondPeriods(
function setLockedBondPeriods(
uint256 retention,
uint256 management
) external onlyRole(DEFAULT_ADMIN_ROLE) {
Expand Down Expand Up @@ -275,13 +279,24 @@ contract CSAccounting is
return WSTETH.getWstETHByStETH(getMissingBondStETH(nodeOperatorId));
}

/// @notice Returns the amount of ETH blocked by the given node operator.
function getBlockedBondETH(
/// @notice Returns information about the locked bond for the given node operator.
/// @param nodeOperatorId id of the node operator to get locked bond info for.
/// @return locked bond info.
function getLockedBondInfo(
uint256 nodeOperatorId
) public view returns (uint256) {
) public view returns (CSBondLock.BondLock memory) {
return CSBondLock._get(nodeOperatorId);
}

/// @notice Returns the amount of locked bond in ETH by the given node operator.
/// @param nodeOperatorId id of the node operator to get locked bond amount.
/// @return amount of locked bond in ETH.
function getActualLockedBondETH(
uint256 nodeOperatorId
) public view returns (uint256) {
return CSBondLock._getActualAmount(nodeOperatorId);
}

/// @notice Returns the required bond ETH (inc. missed and excess) for the given node operator to upload new keys.
/// @param nodeOperatorId id of the node operator to get required bond for.
/// @return required bond ETH.
Expand Down Expand Up @@ -377,10 +392,10 @@ contract CSAccounting is
) public view returns (uint256) {
uint256 activeKeys = _getNodeOperatorActiveKeys(nodeOperatorId);
uint256 currentBond = _ethByShares(_bondShares[nodeOperatorId]);
uint256 blockedBond = getBlockedBondETH(nodeOperatorId);
if (currentBond > blockedBond) {
uint256 lockedBond = getActualLockedBondETH(nodeOperatorId);
if (currentBond > lockedBond) {
uint256 multiplier = getBondMultiplier(nodeOperatorId);
currentBond -= blockedBond;
currentBond -= lockedBond;
uint256 bondedKeys = _getKeysCountByBondAmount(
currentBond,
multiplier
Expand Down Expand Up @@ -696,33 +711,35 @@ contract CSAccounting is
CSBondLock._lock(nodeOperatorId, amount);
}

/// @notice Releases blocked bond ETH for the given node operator.
/// @param nodeOperatorId id of the node operator to release blocked bond for.
/// @notice Releases locked bond ETH for the given node operator.
/// @param nodeOperatorId id of the node operator to release locked bond for.
/// @param amount amount of ETH to release.
function releaseBlockedBondETH(
function releaseLockedBondETH(
uint256 nodeOperatorId,
uint256 amount
)
external
onlyRole(EL_REWARDS_STEALING_PENALTY_INIT_ROLE)
onlyRole(EL_REWARDS_STEALING_PENALTY_RELEASE_ROLE)
onlyExistingNodeOperator(nodeOperatorId)
{
CSBondLock._release(nodeOperatorId, amount);
CSBondLock._reduceAmount(nodeOperatorId, amount);
emit BondLockReleased(nodeOperatorId, amount);
}

/// @notice Compensates blocked bond ETH for the given node operator.
/// @param nodeOperatorId id of the node operator to compensate blocked bond for.
function compensateBlockedBondETH(
/// @notice Compensates locked bond ETH for the given node operator.
/// @param nodeOperatorId id of the node operator to compensate locked bond for.
function compensateLockedBondETH(
uint256 nodeOperatorId
) external payable onlyExistingNodeOperator(nodeOperatorId) {
CSBondLock._compensate(nodeOperatorId, msg.value);
payable(LIDO_LOCATOR.elRewardsVault()).transfer(msg.value);
CSBondLock._reduceAmount(nodeOperatorId, msg.value);
emit BondLockCompensated(nodeOperatorId, msg.value);
}

/// @dev Should be called by the committee. Doesn't settle blocked bond if it is in the safe frame (1 day)
/// @notice Settles blocked bond for the given node operators.
/// @param nodeOperatorIds ids of the node operators to settle blocked bond for.
function settleBlockedBondETH(
/// @dev Should be called by the committee. Doesn't settle locked bond if it is in the safe frame (1 day)
/// @notice Settles locked bond for the given node operators.
/// @param nodeOperatorIds ids of the node operators to settle locked bond for.
function settleLockedBondETH(
uint256[] memory nodeOperatorIds
) external onlyRole(EL_REWARDS_STEALING_PENALTY_SETTLE_ROLE) {
CSBondLock._settle(nodeOperatorIds);
Expand Down Expand Up @@ -828,7 +845,7 @@ contract CSAccounting is
_getNodeOperatorActiveKeys(nodeOperatorId),
getBondMultiplier(nodeOperatorId)
) +
getBlockedBondETH(nodeOperatorId);
getActualLockedBondETH(nodeOperatorId);
}

function _bondSharesSummary(
Expand All @@ -842,7 +859,7 @@ contract CSAccounting is
getBondMultiplier(nodeOperatorId)
)
) +
_sharesByEth(getBlockedBondETH(nodeOperatorId));
_sharesByEth(getActualLockedBondETH(nodeOperatorId));
}

function _sharesByEth(uint256 ethAmount) internal view returns (uint256) {
Expand Down
41 changes: 19 additions & 22 deletions src/CSBondLock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ abstract contract CSBondLockBase {
uint256 newAmount,
uint256 retentionUntil
);
event BondLockCompensated(uint256 indexed nodeOperatorId, uint256 amount);
event BondLockReleased(uint256 indexed nodeOperatorId, uint256 amount);
event BondLockPeriodsChanged(
uint256 retentionPeriod,
uint256 managementPeriod
);

error InvalidBondLockRetentionPeriod();
error InvalidBondLockPeriods();
error InvalidBondLockAmount();
}

Expand Down Expand Up @@ -44,6 +46,7 @@ abstract contract CSBondLock is CSBondLockBase {
_validateBondLockPeriods(retention, management);
_bondLockRetentionPeriod = retention;
_bondLockManagementPeriod = management;
emit BondLockPeriodsChanged(retention, management);
}

function getBondLockPeriods()
Expand All @@ -64,12 +67,21 @@ abstract contract CSBondLock is CSBondLockBase {
management < MIN_BOND_LOCK_MANAGEMENT_PERIOD ||
management > MAX_BOND_LOCK_MANAGEMENT_PERIOD
) {
revert InvalidBondLockRetentionPeriod();
revert InvalidBondLockPeriods();
}
}

/// @notice Returns the amount and retention time of locked bond by the given node operator.
function _get(
uint256 nodeOperatorId
) internal view returns (BondLock memory) {
return _bondLock[nodeOperatorId];
}

/// @notice Returns the amount of locked bond by the given node operator.
function _get(uint256 nodeOperatorId) internal view returns (uint256) {
function _getActualAmount(
uint256 nodeOperatorId
) internal view returns (uint256) {
if (_bondLock[nodeOperatorId].retentionUntil >= block.timestamp) {
return _bondLock[nodeOperatorId].amount;
}
Expand Down Expand Up @@ -121,23 +133,8 @@ abstract contract CSBondLock is CSBondLockBase {
}
}

/// @notice Releases blocked bond ETH for the given node operator.
/// @param nodeOperatorId id of the node operator to release blocked bond for.
/// @param amount amount of ETH to release.
function _release(uint256 nodeOperatorId, uint256 amount) internal {
emit BondLockReleased(nodeOperatorId, amount);
_reduceAmount(nodeOperatorId, amount);
}

/// @notice Compensates blocked bond ETH for the given node operator.
/// @param nodeOperatorId id of the node operator to compensate blocked bond for.
function _compensate(uint256 nodeOperatorId, uint256 amount) internal {
emit BondLockCompensated(nodeOperatorId, amount);
_reduceAmount(nodeOperatorId, amount);
}

function _reduceAmount(uint256 nodeOperatorId, uint256 amount) private {
uint256 blocked = _get(nodeOperatorId);
function _reduceAmount(uint256 nodeOperatorId, uint256 amount) internal {
uint256 blocked = _getActualAmount(nodeOperatorId);
if (amount == 0) {
revert InvalidBondLockAmount();
}
Expand Down
Loading

0 comments on commit c77fac2

Please sign in to comment.