EigenLayerVerifier
Overview
EigenLayerVerifier is a custom ICustomVerifier implementation tailored to securely authorize calls to EigenLayer contracts like DelegationManager, StrategyManager, and RewardsCoordinator. It uses strict role-based gating, exact calldata matching, and entity-specific validation to ensure that only authorized vaults and bots can interact with EigenLayer staking, delegation, withdrawal, and rewards workflows.
Purpose
This verifier protects EigenLayer operations by:
Ensuring only whitelisted entities (vaults, strategies, operators) can execute actions
Verifying target contracts and function selectors precisely
Enforcing exact calldata encoding to eliminate any ambiguity or abuse
Role Definitions
CALLER_ROLE
Address allowed to initiate EigenLayer calls (typically curators)
ASSET_ROLE
Whitelisted ERC20 token allowed in strategy deposits or withdrawals
STRATEGY_ROLE
Whitelisted EigenLayer strategy contracts
OPERATOR_ROLE
Approved EigenLayer operator address for delegation
MELLOW_VAULT_ROLE
Whitelisted vaults acting as stakers or earners (usually Subvault )
RECEIVER_ROLE
Authorized receivers for claimed rewards
Constructor
constructor(address delegationManager_, address strategyManager_, address rewardsCoordinator_, string memory name_, uint256 version_)Initializes the verifier by:
Setting immutable references to EigenLayer’s:
DelegationManagerStrategyManagerRewardsCoordinator
Inheriting access control via
OwnedCustomVerifier
verifyCall
verifyCallfunction verifyCall(
address who,
address where,
uint256 value,
bytes calldata callData,
bytes calldata /* verificationData */
) external view override returns (bool)General Preconditions
whomust haveCALLER_ROLEvaluemust be 0 (no ETH allowed)callData.length >= 4(valid selector)
Validated Targets & Selectors
1. StrategyManager – depositIntoStrategy
depositIntoStrategydepositIntoStrategy(IStrategy, address asset, uint256 shares)Strategy must have
STRATEGY_ROLEAsset must have
ASSET_ROLEShares must be non-zero
Calldata must match
2. DelegationManager
delegateTo(address operator, SignatureWithExpiry signature, bytes32 salt)Operator must have
OPERATOR_ROLECalldata must match
queueWithdrawals(QueuedWithdrawalParams[] params)Only one
params.length == 1allowedParam must include:
One strategy with
STRATEGY_ROLEOne deposit share > 0
Calldata must match
completeQueuedWithdrawal(Withdrawal, address[] tokens, bool receiveAsTokens)receiveAsTokensmust betrueWithdrawal must:
Have only one strategy with
STRATEGY_ROLEHave
stakerwithMELLOW_VAULT_ROLE
tokens.length == 1and token must haveASSET_ROLECalldata must match
3. RewardsCoordinator – processClaim
processClaimSelector:
processClaim(RewardsMerkleClaim claimData, address receiver)Checks:
claimData.earnerLeaf.earnermust haveMELLOW_VAULT_ROLEreceivermust haveRECEIVER_ROLECalldata must match
Security Properties
Role enforcement: Prevents unauthorized usage of EigenLayer functions
Exact calldata match: Avoids incorrect encoding or maliciously crafted data
Zero ETH transfers: Disallows unexpected native token usage
Single param enforcement (withdrawals): Minimizes complexity and risk surface