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

ejector fix #322

Merged
merged 5 commits into from
Nov 20, 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
48 changes: 25 additions & 23 deletions src/EjectionManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -74,16 +74,30 @@ contract EjectionManager is IEjectionManager, OwnableUpgradeable{
uint32 ejectedOperators;

bool ratelimitHit;
for(uint8 j = 0; j < _operatorIds[i].length; ++j) {
uint256 operatorStake = stakeRegistry.getCurrentStake(_operatorIds[i][j], quorumNumber);
if(amountEjectable > 0){
for(uint8 j = 0; j < _operatorIds[i].length; ++j) {
uint256 operatorStake = stakeRegistry.getCurrentStake(_operatorIds[i][j], quorumNumber);

//if caller is ejector enforce ratelimit
if(
isEjector[msg.sender] &&
quorumEjectionParams[quorumNumber].rateLimitWindow > 0 &&
stakeForEjection + operatorStake > amountEjectable
){
ratelimitHit = true;
//if caller is ejector enforce ratelimit
if(
isEjector[msg.sender] &&
quorumEjectionParams[quorumNumber].rateLimitWindow > 0 &&
stakeForEjection + operatorStake > amountEjectable
){
ratelimitHit = true;

stakeForEjection += operatorStake;
++ejectedOperators;

registryCoordinator.ejectOperator(
registryCoordinator.getOperatorFromId(_operatorIds[i][j]),
abi.encodePacked(quorumNumber)
);

emit OperatorEjected(_operatorIds[i][j], quorumNumber);

break;
}

stakeForEjection += operatorStake;
++ejectedOperators;
Expand All @@ -92,25 +106,13 @@ contract EjectionManager is IEjectionManager, OwnableUpgradeable{
registryCoordinator.getOperatorFromId(_operatorIds[i][j]),
abi.encodePacked(quorumNumber)
);

emit OperatorEjected(_operatorIds[i][j], quorumNumber);

break;
}

stakeForEjection += operatorStake;
++ejectedOperators;

registryCoordinator.ejectOperator(
registryCoordinator.getOperatorFromId(_operatorIds[i][j]),
abi.encodePacked(quorumNumber)
);

emit OperatorEjected(_operatorIds[i][j], quorumNumber);
}

//record the stake ejected if ejector and ratelimit enforced
if(isEjector[msg.sender]){
if(isEjector[msg.sender] && stakeForEjection > 0){
stakeEjectedForQuorum[quorumNumber].push(StakeEjection({
timestamp: block.timestamp,
stakeEjected: stakeForEjection
Expand Down
49 changes: 49 additions & 0 deletions test/unit/EjectionManagerUnit.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,55 @@ contract EjectionManagerUnitTests is MockAVSDeployer {
}
}

function testEjectOperators_NoEjectionForNoEjectableStake() public {
uint8 operatorsCanEject = 2;
uint8 operatorsToEject = 10;
uint8 numOperators = 10;
uint96 stake = 1 ether;
_registerOperaters(numOperators, stake);

bytes32[][] memory operatorIds = new bytes32[][](numQuorums);
for (uint8 i = 0; i < numQuorums; i++) {
operatorIds[i] = new bytes32[](operatorsToEject);
for (uint j = 0; j < operatorsToEject; j++) {
operatorIds[i][j] = registryCoordinator.getOperatorId(_incrementAddress(defaultOperator, j));
}
}

for(uint8 i = 0; i < operatorsToEject; i++) {
assertEq(uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), uint8(IRegistryCoordinator.OperatorStatus.REGISTERED));
}

for(uint8 i = 0; i < numQuorums; i++) {
for(uint8 j = 0; j < operatorsCanEject; j++) {
cheats.expectEmit(true, true, true, true, address(ejectionManager));
emit OperatorEjected(operatorIds[i][j], i);
}
}

cheats.prank(ejector);
ejectionManager.ejectOperators(operatorIds);

for(uint8 i = 0; i < operatorsCanEject; i++) {
assertEq(uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), uint8(IRegistryCoordinator.OperatorStatus.DEREGISTERED));
}

for(uint8 i = operatorsCanEject; i < operatorsToEject; i++) {
assertEq(uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), uint8(IRegistryCoordinator.OperatorStatus.REGISTERED));
}

cheats.prank(ejector);
ejectionManager.ejectOperators(operatorIds);

for(uint8 i = 0; i < operatorsCanEject; i++) {
assertEq(uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), uint8(IRegistryCoordinator.OperatorStatus.DEREGISTERED));
}

for(uint8 i = operatorsCanEject; i < operatorsToEject; i++) {
assertEq(uint8(registryCoordinator.getOperatorStatus(_incrementAddress(defaultOperator, i))), uint8(IRegistryCoordinator.OperatorStatus.REGISTERED));
}
}

function testEjectOperators_MultipleOperatorMultipleTimesInsideRatelimit() public {
uint8 operatorsToEject = 4;
uint8 numOperators = 100;
Expand Down
Loading