Skip to content
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

Fixes Statemind #60

Merged
merged 7 commits into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/contracts/delegator/BaseDelegator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -181,18 +181,18 @@ abstract contract BaseDelegator is
function onSlash(
bytes32 subnetwork,
address operator,
uint256 slashedAmount,
uint256 amount,
uint48 captureTimestamp,
bytes memory data
) external nonReentrant {
if (IVault(vault).slasher() != msg.sender) {
if (msg.sender != IVault(vault).slasher()) {
revert NotSlasher();
}

address hook_ = hook;
if (hook_ != address(0)) {
bytes memory calldata_ =
abi.encodeCall(IDelegatorHook.onSlash, (subnetwork, operator, slashedAmount, captureTimestamp, data));
abi.encodeCall(IDelegatorHook.onSlash, (subnetwork, operator, amount, captureTimestamp, data));

if (gasleft() < HOOK_RESERVE + HOOK_GAS_LIMIT * 64 / 63) {
revert InsufficientHookGas();
Expand All @@ -203,7 +203,7 @@ abstract contract BaseDelegator is
}
}

emit OnSlash(subnetwork, operator, slashedAmount);
emit OnSlash(subnetwork, operator, amount, captureTimestamp);
}

function _initialize(
Expand Down
8 changes: 2 additions & 6 deletions src/contracts/delegator/FullRestakeDelegator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -169,23 +169,19 @@ contract FullRestakeDelegator is BaseDelegator, IFullRestakeDelegator {
revert ZeroAddressRoleHolder();
}

if (hasRole(NETWORK_LIMIT_SET_ROLE, params.networkLimitSetRoleHolders[i])) {
if (!_grantRole(NETWORK_LIMIT_SET_ROLE, params.networkLimitSetRoleHolders[i])) {
revert DuplicateRoleHolder();
}

_grantRole(NETWORK_LIMIT_SET_ROLE, params.networkLimitSetRoleHolders[i]);
}

for (uint256 i; i < params.operatorNetworkLimitSetRoleHolders.length; ++i) {
if (params.operatorNetworkLimitSetRoleHolders[i] == address(0)) {
revert ZeroAddressRoleHolder();
}

if (hasRole(OPERATOR_NETWORK_LIMIT_SET_ROLE, params.operatorNetworkLimitSetRoleHolders[i])) {
if (!_grantRole(OPERATOR_NETWORK_LIMIT_SET_ROLE, params.operatorNetworkLimitSetRoleHolders[i])) {
revert DuplicateRoleHolder();
}

_grantRole(OPERATOR_NETWORK_LIMIT_SET_ROLE, params.operatorNetworkLimitSetRoleHolders[i]);
}

return params.baseParams;
Expand Down
8 changes: 2 additions & 6 deletions src/contracts/delegator/NetworkRestakeDelegator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -202,23 +202,19 @@ contract NetworkRestakeDelegator is BaseDelegator, INetworkRestakeDelegator {
revert ZeroAddressRoleHolder();
}

if (hasRole(NETWORK_LIMIT_SET_ROLE, params.networkLimitSetRoleHolders[i])) {
if (!_grantRole(NETWORK_LIMIT_SET_ROLE, params.networkLimitSetRoleHolders[i])) {
revert DuplicateRoleHolder();
}

_grantRole(NETWORK_LIMIT_SET_ROLE, params.networkLimitSetRoleHolders[i]);
}

for (uint256 i; i < params.operatorNetworkSharesSetRoleHolders.length; ++i) {
if (params.operatorNetworkSharesSetRoleHolders[i] == address(0)) {
revert ZeroAddressRoleHolder();
}

if (hasRole(OPERATOR_NETWORK_SHARES_SET_ROLE, params.operatorNetworkSharesSetRoleHolders[i])) {
if (!_grantRole(OPERATOR_NETWORK_SHARES_SET_ROLE, params.operatorNetworkSharesSetRoleHolders[i])) {
revert DuplicateRoleHolder();
}

_grantRole(OPERATOR_NETWORK_SHARES_SET_ROLE, params.operatorNetworkSharesSetRoleHolders[i]);
}

return params.baseParams;
Expand Down
4 changes: 1 addition & 3 deletions src/contracts/delegator/OperatorSpecificDelegator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -143,11 +143,9 @@ contract OperatorSpecificDelegator is BaseDelegator, IOperatorSpecificDelegator
revert ZeroAddressRoleHolder();
}

if (hasRole(NETWORK_LIMIT_SET_ROLE, params.networkLimitSetRoleHolders[i])) {
if (!_grantRole(NETWORK_LIMIT_SET_ROLE, params.networkLimitSetRoleHolders[i])) {
revert DuplicateRoleHolder();
}

_grantRole(NETWORK_LIMIT_SET_ROLE, params.networkLimitSetRoleHolders[i]);
}

operator = params.operator;
Expand Down
10 changes: 0 additions & 10 deletions src/contracts/slasher/BaseSlasher.sol
Original file line number Diff line number Diff line change
Expand Up @@ -129,16 +129,6 @@ abstract contract BaseSlasher is Entity, StaticDelegateCallable, ReentrancyGuard
}
}

function _checkLatestSlashedCaptureTimestamp(
bytes32 subnetwork,
address operator,
uint48 captureTimestamp
) internal view {
if (captureTimestamp < latestSlashedCaptureTimestamp[subnetwork][operator]) {
revert OutdatedCaptureTimestamp();
}
}

function _updateLatestSlashedCaptureTimestamp(
bytes32 subnetwork,
address operator,
Expand Down
21 changes: 9 additions & 12 deletions src/contracts/slasher/VetoSlasher.sol
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,13 @@ contract VetoSlasher is BaseSlasher, IVetoSlasher {
revert SlashPeriodEnded();
}

_checkLatestSlashedCaptureTimestamp(request.subnetwork, request.operator, request.captureTimestamp);
(uint256 slashableStake_, uint256 stakeAt) = _slashableStake(
request.subnetwork, request.operator, request.captureTimestamp, executeSlashHints.slashableStakeHints
);
slashedAmount = Math.min(request.amount, slashableStake_);
if (slashedAmount == 0) {
revert InsufficientSlash();
}

if (request.completed) {
revert SlashRequestCompleted();
Expand All @@ -163,14 +169,7 @@ contract VetoSlasher is BaseSlasher, IVetoSlasher {

_updateLatestSlashedCaptureTimestamp(request.subnetwork, request.operator, request.captureTimestamp);

(uint256 slashableStake_, uint256 stakeAt) = _slashableStake(
request.subnetwork, request.operator, request.captureTimestamp, executeSlashHints.slashableStakeHints
);
slashedAmount = Math.min(request.amount, slashableStake_);

if (slashedAmount > 0) {
_updateCumulativeSlash(request.subnetwork, request.operator, slashedAmount);
}
_updateCumulativeSlash(request.subnetwork, request.operator, slashedAmount);

_delegatorOnSlash(
request.subnetwork,
Expand All @@ -187,9 +186,7 @@ contract VetoSlasher is BaseSlasher, IVetoSlasher {
)
);

if (slashedAmount > 0) {
_vaultOnSlash(slashedAmount, request.captureTimestamp);
}
_vaultOnSlash(slashedAmount, request.captureTimestamp);

emit ExecuteSlash(slashIndex, slashedAmount);
}
Expand Down
16 changes: 4 additions & 12 deletions src/contracts/vault/Vault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ contract Vault is VaultStorage, MigratableEntity, AccessControlUpgradeable, IVau
/**
* @inheritdoc IVault
*/
function onSlash(uint256 slashedAmount, uint48 captureTimestamp) external nonReentrant {
function onSlash(uint256 amount, uint48 captureTimestamp) external nonReentrant returns (uint256 slashedAmount) {
if (msg.sender != slasher) {
revert NotSlasher();
}
Expand All @@ -229,7 +229,7 @@ contract Vault is VaultStorage, MigratableEntity, AccessControlUpgradeable, IVau
uint256 nextWithdrawals = withdrawals[currentEpoch_ + 1];
if (captureEpoch == currentEpoch_) {
uint256 slashableStake = activeStake_ + nextWithdrawals;
slashedAmount = Math.min(slashedAmount, slashableStake);
slashedAmount = Math.min(amount, slashableStake);
if (slashedAmount > 0) {
uint256 activeSlashed = slashedAmount.mulDiv(activeStake_, slashableStake);
uint256 nextWithdrawalsSlashed = slashedAmount - activeSlashed;
Expand All @@ -240,7 +240,7 @@ contract Vault is VaultStorage, MigratableEntity, AccessControlUpgradeable, IVau
} else {
uint256 withdrawals_ = withdrawals[currentEpoch_];
uint256 slashableStake = activeStake_ + withdrawals_ + nextWithdrawals;
slashedAmount = Math.min(slashedAmount, slashableStake);
slashedAmount = Math.min(amount, slashableStake);
if (slashedAmount > 0) {
uint256 activeSlashed = slashedAmount.mulDiv(activeStake_, slashableStake);
uint256 nextWithdrawalsSlashed = slashedAmount.mulDiv(nextWithdrawals, slashableStake);
Expand All @@ -261,7 +261,7 @@ contract Vault is VaultStorage, MigratableEntity, AccessControlUpgradeable, IVau
IERC20(collateral).safeTransfer(burner, slashedAmount);
}

emit OnSlash(msg.sender, slashedAmount);
emit OnSlash(amount, captureTimestamp, slashedAmount);
}

/**
Expand Down Expand Up @@ -294,10 +294,6 @@ contract Vault is VaultStorage, MigratableEntity, AccessControlUpgradeable, IVau
revert AlreadySet();
}

if (status && !depositWhitelist) {
revert NoDepositWhitelist();
}

isDepositorWhitelisted[account] = status;

emit SetDepositorWhitelistStatus(account, status);
Expand All @@ -324,10 +320,6 @@ contract Vault is VaultStorage, MigratableEntity, AccessControlUpgradeable, IVau
function setDepositLimit(
uint256 limit
) external nonReentrant onlyRole(DEPOSIT_LIMIT_SET_ROLE) {
if (limit != 0 && !isDepositLimit) {
revert NoDepositLimit();
}

if (depositLimit == limit) {
revert AlreadySet();
}
Expand Down
11 changes: 6 additions & 5 deletions src/interfaces/delegator/IBaseDelegator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,13 @@ interface IBaseDelegator is IEntity {
event SetMaxNetworkLimit(bytes32 indexed subnetwork, uint256 amount);

/**
* @notice Emitted when a slash happened.
* @notice Emitted when a slash happens.
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @param operator address of the operator
* @param slashedAmount amount of the collateral slashed
* @param amount amount of the collateral to be slashed
* @param captureTimestamp time point when the stake was captured
*/
event OnSlash(bytes32 indexed subnetwork, address indexed operator, uint256 slashedAmount);
event OnSlash(bytes32 indexed subnetwork, address indexed operator, uint256 amount, uint48 captureTimestamp);

/**
* @notice Emitted when a hook is set.
Expand Down Expand Up @@ -174,15 +175,15 @@ interface IBaseDelegator is IEntity {
* @notice Called when a slash happens.
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @param operator address of the operator
* @param slashedAmount amount of the collateral slashed
* @param amount amount of the collateral slashed
* @param captureTimestamp time point when the stake was captured
* @param data some additional data
* @dev Only the vault's slasher can call this function.
*/
function onSlash(
bytes32 subnetwork,
address operator,
uint256 slashedAmount,
uint256 amount,
uint48 captureTimestamp,
bytes calldata data
) external;
Expand Down
4 changes: 2 additions & 2 deletions src/interfaces/delegator/IDelegatorHook.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ interface IDelegatorHook {
* @notice Called when a slash happens.
* @param subnetwork full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
* @param operator address of the operator
* @param slashedAmount amount of the collateral slashed
* @param amount amount of the collateral to be slashed
* @param captureTimestamp time point when the stake was captured
* @param data some additional data
*/
function onSlash(
bytes32 subnetwork,
address operator,
uint256 slashedAmount,
uint256 amount,
uint48 captureTimestamp,
bytes calldata data
) external;
Expand Down
1 change: 0 additions & 1 deletion src/interfaces/slasher/IBaseSlasher.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {IEntity} from "../common/IEntity.sol";
interface IBaseSlasher is IEntity {
error NotNetworkMiddleware();
error NotVault();
error OutdatedCaptureTimestamp();

/**
* @notice Hints for a slashable stake.
Expand Down
4 changes: 2 additions & 2 deletions src/interfaces/slasher/ISlasher.sol
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ interface ISlasher {
* @notice Emitted when a slash is performed.
* @param subnetwork subnetwork that requested the slash
* @param operator operator that is slashed
* @param slashedAmount amount of the collateral slashed
* @param slashedAmount virtual amount of the collateral slashed
* @param captureTimestamp time point when the stake was captured
*/
event Slash(bytes32 indexed subnetwork, address indexed operator, uint256 slashedAmount, uint48 captureTimestamp);
Expand All @@ -41,7 +41,7 @@ interface ISlasher {
* @param amount maximum amount of the collateral to be slashed
* @param captureTimestamp time point when the stake was captured
* @param hints hints for checkpoints' indexes
* @return slashedAmount amount of the collateral slashed
* @return slashedAmount virtual amount of the collateral slashed
* @dev Only a network middleware can call this function.
*/
function slash(
Expand Down
5 changes: 2 additions & 3 deletions src/interfaces/slasher/IVetoSlasher.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ interface IVetoSlasher {
error SlashPeriodEnded();
error SlashRequestCompleted();
error SlashRequestNotExist();
error VaultNotInitialized();
error VetoPeriodEnded();
error VetoPeriodNotEnded();

Expand Down Expand Up @@ -117,7 +116,7 @@ interface IVetoSlasher {
/**
* @notice Emitted when a slash request is executed.
* @param slashIndex index of the slash request
* @param slashedAmount amount of the collateral slashed
* @param slashedAmount virtual amount of the collateral slashed
*/
event ExecuteSlash(uint256 indexed slashIndex, uint256 slashedAmount);

Expand Down Expand Up @@ -222,7 +221,7 @@ interface IVetoSlasher {
* @notice Execute a slash with a given slash index using hints.
* @param slashIndex index of the slash request
* @param hints hints for checkpoints' indexes
* @return slashedAmount amount of the collateral slashed
* @return slashedAmount virtual amount of the collateral slashed
* @dev Only a network middleware can call this function.
*/
function executeSlash(uint256 slashIndex, bytes calldata hints) external returns (uint256 slashedAmount);
Expand Down
18 changes: 9 additions & 9 deletions src/interfaces/vault/IVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ interface IVault is IMigratableEntity, IVaultStorage {
error InvalidRecipient();
error InvalidSlasher();
error MissingRoles();
error NoDepositLimit();
error NoDepositWhitelist();
error NotDelegator();
error NotSlasher();
error NotWhitelistedDepositor();
Expand Down Expand Up @@ -114,11 +112,12 @@ interface IVault is IMigratableEntity, IVaultStorage {
event ClaimBatch(address indexed claimer, address indexed recipient, uint256[] epochs, uint256 amount);

/**
* @notice Emitted when a slash happened.
* @param slasher address of the slasher
* @param slashedAmount amount of the collateral slashed
* @notice Emitted when a slash happens.
* @param amount amount of the collateral to slash
* @param captureTimestamp time point when the stake was captured
* @param slashedAmount real amount of the collateral slashed
*/
event OnSlash(address indexed slasher, uint256 slashedAmount);
event OnSlash(uint256 amount, uint48 captureTimestamp, uint256 slashedAmount);

/**
* @notice Emitted when a deposit whitelist status is enabled/disabled.
Expand Down Expand Up @@ -214,7 +213,7 @@ interface IVault is IMigratableEntity, IVaultStorage {
* @notice Deposit collateral into the vault.
* @param onBehalfOf account the deposit is made on behalf of
* @param amount amount of the collateral to deposit
* @return depositedAmount amount of the collateral deposited
* @return depositedAmount real amount of the collateral deposited
* @return mintedShares amount of the active shares minted
*/
function deposit(
Expand Down Expand Up @@ -258,11 +257,12 @@ interface IVault is IMigratableEntity, IVaultStorage {

/**
* @notice Slash callback for burning collateral.
* @param slashedAmount amount to slash
* @param amount amount to slash
* @param captureTimestamp time point when the stake was captured
* @return slashedAmount real amount of the collateral slashed
* @dev Only the slasher can call this function.
*/
function onSlash(uint256 slashedAmount, uint48 captureTimestamp) external;
function onSlash(uint256 amount, uint48 captureTimestamp) external returns (uint256 slashedAmount);

/**
* @notice Enable/disable deposit whitelist.
Expand Down
Loading
Loading