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

test: unit test slashers #380

Merged
merged 15 commits into from
Feb 5, 2025
Merged
Show file tree
Hide file tree
Changes from 13 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
10 changes: 0 additions & 10 deletions src/RegistryCoordinator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -208,16 +208,6 @@ contract RegistryCoordinator is IRegistryCoordinator, SlashingRegistryCoordinato
return (1 << quorumCount) - 1;
}

/**
* @notice Returns the message hash that an operator must sign to register their BLS public key.
* @param operator is the address of the operator registering their BLS public key
*/
function calculatePubkeyRegistrationMessageHash(
address operator
) public view returns (bytes32) {
return _hashTypedDataV4(keccak256(abi.encode(PUBKEY_REGISTRATION_TYPEHASH, operator)));
}

/// @dev need to override function here since its defined in both these contracts
function owner()
public
Expand Down
10 changes: 10 additions & 0 deletions src/SlashingRegistryCoordinator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -1077,6 +1077,16 @@ contract SlashingRegistryCoordinator is
);
}

/**
* @notice Returns the message hash that an operator must sign to register their BLS public key.
* @param operator is the address of the operator registering their BLS public key
*/
function calculatePubkeyRegistrationMessageHash(
address operator
) public view returns (bytes32) {
return _hashTypedDataV4(keccak256(abi.encode(PUBKEY_REGISTRATION_TYPEHASH, operator)));
}

/// @dev need to override function here since its defined in both these contracts
function owner()
public
Expand Down
8 changes: 8 additions & 0 deletions src/interfaces/ISlashingRegistryCoordinator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,14 @@ interface ISlashingRegistryCoordinator is

/// VIEW

/**
* @notice Returns the hash of the message that operators must sign with their BLS key to register
* @param operator The operator's Ethereum address
*/
function calculatePubkeyRegistrationMessageHash(
address operator
) external view returns (bytes32);

/**
* @notice Returns the operator set parameters for a given quorum.
* @param quorumNumber The identifier of the quorum to query.
Expand Down
10 changes: 9 additions & 1 deletion src/slashers/InstantSlasher.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,30 @@ pragma solidity ^0.8.27;
import {IStrategy} from "eigenlayer-contracts/src/contracts/interfaces/IStrategy.sol";
import {IAllocationManager} from
"eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol";
import {ISlashingRegistryCoordinator} from "../interfaces/ISlashingRegistryCoordinator.sol";
import {SlasherBase} from "./base/SlasherBase.sol";
import {ISlashingRegistryCoordinator} from "../interfaces/ISlashingRegistryCoordinator.sol";

/// @title InstantSlasher
/// @notice A slashing contract that immediately executes slashing requests without any delay or veto period
/// @dev Extends SlasherBase to provide access controlled slashing functionality
contract InstantSlasher is SlasherBase {
constructor(
IAllocationManager _allocationManager,
ISlashingRegistryCoordinator _slashingRegistryCoordinator,
address _slasher
) SlasherBase(_allocationManager, _slashingRegistryCoordinator) {}

/// @notice Initializes the contract with a slasher address
/// @param _slasher Address authorized to create and fulfill slashing requests
function initialize(
address _slasher
) external initializer {
__SlasherBase_init(_slasher);
}

/// @notice Immediately executes a slashing request
stevennevins marked this conversation as resolved.
Show resolved Hide resolved
/// @param _slashingParams Parameters defining the slashing request including operator and amount
/// @dev Can only be called by the authorized slasher
function fulfillSlashingRequest(
IAllocationManager.SlashingParams memory _slashingParams
) external virtual onlySlasher {
Expand Down
28 changes: 28 additions & 0 deletions src/slashers/VetoableSlasher.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,21 @@ import {IAllocationManager} from
import {SlasherBase} from "./base/SlasherBase.sol";
import {ISlashingRegistryCoordinator} from "../interfaces/ISlashingRegistryCoordinator.sol";

/// @title VetoableSlasher
/// @notice A slashing contract that implements a veto mechanism allowing a designated committee to cancel slashing requests
/// @dev Extends SlasherBase and adds a veto period during which slashing requests can be cancelled
contract VetoableSlasher is SlasherBase {
/// @notice Duration of the veto period during which the veto committee can cancel slashing requests
/// @dev Set to 3 days (259,200 seconds)
uint256 public constant VETO_PERIOD = 3 days;

/// @notice Address of the committee that has veto power over slashing requests
address public vetoCommittee;

/// @notice Mapping of request IDs to their corresponding slashing request details
mapping(uint256 => SlashingRequest) public slashingRequests;

/// @notice Modifier to restrict function access to only the veto committee
modifier onlyVetoCommittee() {
_checkVetoCommittee(msg.sender);
_;
Expand All @@ -23,17 +32,26 @@ contract VetoableSlasher is SlasherBase {
ISlashingRegistryCoordinator _slashingRegistryCoordinator
) SlasherBase(_allocationManager, _slashingRegistryCoordinator) {}

/// @notice Initializes the contract with a veto committee and slasher address
0xClandestine marked this conversation as resolved.
Show resolved Hide resolved
/// @param _vetoCommittee Address of the committee that can veto slashing requests
/// @param _slasher Address authorized to create and fulfill slashing requests
function initialize(address _vetoCommittee, address _slasher) external virtual initializer {
__SlasherBase_init(_slasher);
vetoCommittee = _vetoCommittee;
}

/// @notice Queues a new slashing request
/// @param params Parameters defining the slashing request including operator and amount
/// @dev Can only be called by the authorized slasher
function queueSlashingRequest(
IAllocationManager.SlashingParams calldata params
) external virtual onlySlasher {
_queueSlashingRequest(params);
}

/// @notice Cancels a pending slashing request
/// @param requestId The ID of the slashing request to cancel
/// @dev Can only be called by the veto committee during the veto period
function cancelSlashingRequest(
uint256 requestId
) external virtual onlyVetoCommittee {
Expand All @@ -49,6 +67,9 @@ contract VetoableSlasher is SlasherBase {
_cancelSlashingRequest(requestId);
}

/// @notice Executes a slashing request after the veto period has passed
/// @param requestId The ID of the slashing request to fulfill
/// @dev Can only be called by the authorized slasher after the veto period
function fulfillSlashingRequest(
uint256 requestId
) external virtual onlySlasher {
Expand All @@ -61,6 +82,8 @@ contract VetoableSlasher is SlasherBase {
_fulfillSlashingRequest(requestId, request.params);
}

/// @notice Internal function to create and store a new slashing request
/// @param params Parameters defining the slashing request
function _queueSlashingRequest(
IAllocationManager.SlashingParams calldata params
) internal virtual {
Expand All @@ -76,13 +99,18 @@ contract VetoableSlasher is SlasherBase {
);
}

/// @notice Internal function to mark a slashing request as cancelled
/// @param requestId The ID of the slashing request to cancel
function _cancelSlashingRequest(
uint256 requestId
) internal virtual {
slashingRequests[requestId].status = SlashingStatus.Cancelled;
emit SlashingRequestCancelled(requestId);
}

/// @notice Internal function to verify if an account is the veto committee
/// @param account The address to check
/// @dev Reverts if the account is not the veto committee
function _checkVetoCommittee(
address account
) internal view virtual {
Expand Down
16 changes: 16 additions & 0 deletions src/slashers/base/SlasherBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,38 @@ import {
} from "eigenlayer-contracts/src/contracts/interfaces/IAllocationManager.sol";
import {IStrategy} from "eigenlayer-contracts/src/contracts/interfaces/IStrategy.sol";

/// @title SlasherBase
/// @notice Base contract for implementing slashing functionality in EigenLayer middleware
/// @dev Provides core slashing functionality and interfaces with EigenLayer's AllocationManager
abstract contract SlasherBase is Initializable, SlasherStorage {
/// @notice Ensures only the authorized slasher can call certain functions
modifier onlySlasher() {
_checkSlasher(msg.sender);
_;
}

/// @notice Constructs the base slasher contract
stevennevins marked this conversation as resolved.
Show resolved Hide resolved
/// @param _allocationManager The EigenLayer allocation manager contract
/// @param _registryCoordinator The registry coordinator for this middleware
constructor(
IAllocationManager _allocationManager,
ISlashingRegistryCoordinator _registryCoordinator
) SlasherStorage(_allocationManager, _registryCoordinator) {
_disableInitializers();
}

/// @notice Initializes the slasher contract with authorized slasher address
/// @param _slasher Address authorized to create and fulfill slashing requests
function __SlasherBase_init(
address _slasher
) internal onlyInitializing {
slasher = _slasher;
}

/// @notice Internal function to execute a slashing request
/// @param _requestId The ID of the slashing request to fulfill
/// @param _params Parameters defining the slashing request including operator, strategies, and amounts
/// @dev Calls AllocationManager.slashOperator to perform the actual slashing
function _fulfillSlashingRequest(
uint256 _requestId,
IAllocationManager.SlashingParams memory _params
Expand All @@ -45,6 +58,9 @@ abstract contract SlasherBase is Initializable, SlasherStorage {
);
}

/// @notice Internal function to verify if an account is the authorized slasher
/// @param account The address to check
/// @dev Reverts if the account is not the authorized slasher
function _checkSlasher(
address account
) internal view virtual {
Expand Down
Loading