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

fix: operator split activation delay lock #947

Merged
merged 2 commits into from
Dec 12, 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
19 changes: 9 additions & 10 deletions src/contracts/core/RewardsCoordinator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -395,16 +395,15 @@ contract RewardsCoordinator is
* @param activatedAt The timestamp when the split is activated.
*/
function _setOperatorSplit(OperatorSplit storage operatorSplit, uint16 split, uint32 activatedAt) internal {
0xrajath marked this conversation as resolved.
Show resolved Hide resolved
// If, the earlier 'new' split is activated, we update the 'old' split with the earlier 'new' split.
// Else, the earlier 'old' split remains the same. This is essentially resetting the activation delay window
// since the earlier split setting didn't complete.
if (block.timestamp >= operatorSplit.activatedAt) {
if (operatorSplit.activatedAt == 0) {
// If the operator split has not been initialized yet, set the old split to the default split.
operatorSplit.oldSplitBips = defaultOperatorSplitBips;
} else {
operatorSplit.oldSplitBips = operatorSplit.newSplitBips;
}
require(
block.timestamp > operatorSplit.activatedAt,
"RewardsCoordinator._setOperatorSplit: earlier split not activated yet"
);
if (operatorSplit.activatedAt == 0) {
// If the operator split has not been initialized yet, set the old split to the default split.
operatorSplit.oldSplitBips = defaultOperatorSplitBips;
} else {
operatorSplit.oldSplitBips = operatorSplit.newSplitBips;
}
operatorSplit.newSplitBips = split;
operatorSplit.activatedAt = activatedAt;
Expand Down
40 changes: 13 additions & 27 deletions src/test/unit/RewardsCoordinatorUnit.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,7 @@ contract RewardsCoordinatorUnitTests_setOperatorAVSSplit is RewardsCoordinatorUn
}

// Testing the split setting for a second time prior to the earlier activation.
function testFuzz_setOperatorAVSSplitSecondTimeBeforePriorActivation(
function testFuzz_Revert_setOperatorAVSSplitSecondTimeBeforePriorActivation(
address operator,
address avs,
uint16 firstSplit,
Expand All @@ -484,25 +484,18 @@ contract RewardsCoordinatorUnitTests_setOperatorAVSSplit is RewardsCoordinatorUn
cheats.assume(operator != address(0));
firstSplit = uint16(bound(firstSplit, 0, ONE_HUNDRED_IN_BIPS));
secondSplit = uint16(bound(secondSplit, 0, ONE_HUNDRED_IN_BIPS));
warpTime = uint32(bound(warpTime, uint32(block.timestamp), uint32(block.timestamp) + activationDelay - 1));
uint16 oldSplit = rewardsCoordinator.getOperatorAVSSplit(operator, avs);
warpTime = uint32(bound(warpTime, uint32(block.timestamp), uint32(block.timestamp) + activationDelay));

// Setting First Split
cheats.prank(operator);
rewardsCoordinator.setOperatorAVSSplit(operator, avs, firstSplit);
// Warping to time before activation of First split
cheats.warp(warpTime);
uint32 activatedAt = uint32(block.timestamp) + activationDelay;

// Setting Second Split
cheats.expectEmit(true, true, true, true, address(rewardsCoordinator));
emit OperatorAVSSplitBipsSet(operator, operator, avs, activatedAt, oldSplit, secondSplit);
// Trying to set Second Split
cheats.prank(operator);
cheats.expectRevert("RewardsCoordinator._setOperatorSplit: earlier split not activated yet");
rewardsCoordinator.setOperatorAVSSplit(operator, avs, secondSplit);

assertEq(oldSplit, rewardsCoordinator.getOperatorAVSSplit(operator, avs), "Incorrect Operator split");
cheats.warp(activatedAt);
assertEq(secondSplit, rewardsCoordinator.getOperatorAVSSplit(operator, avs), "Incorrect Operator split");
}

// Testing the split setting for a second time after earlier activation.
Expand All @@ -517,7 +510,7 @@ contract RewardsCoordinatorUnitTests_setOperatorAVSSplit is RewardsCoordinatorUn
firstSplit = uint16(bound(firstSplit, 0, ONE_HUNDRED_IN_BIPS));
secondSplit = uint16(bound(secondSplit, 0, ONE_HUNDRED_IN_BIPS));
warpTime = uint32(
bound(warpTime, uint32(block.timestamp) + activationDelay, type(uint32).max - activationDelay)
bound(warpTime, uint32(block.timestamp) + activationDelay + 1, type(uint32).max - activationDelay)
);

// Setting First Split
Expand Down Expand Up @@ -577,7 +570,7 @@ contract RewardsCoordinatorUnitTests_setOperatorPISplit is RewardsCoordinatorUni
rewardsCoordinator.setOperatorPISplit(operator, split);
}

function testFuzz_setOperatorAVSSplit(address operator, uint16 split) public filterFuzzedAddressInputs(operator) {
function testFuzz_setOperatorPISplit(address operator, uint16 split) public filterFuzzedAddressInputs(operator) {
cheats.assume(operator != address(0));
split = uint16(bound(split, 0, ONE_HUNDRED_IN_BIPS));
uint32 activatedAt = uint32(block.timestamp) + activationDelay;
Expand All @@ -594,7 +587,7 @@ contract RewardsCoordinatorUnitTests_setOperatorPISplit is RewardsCoordinatorUni
}

// Testing that the split has been initialized for the first time.
function testFuzz_setOperatorAVSSplitFirstTime(
function testFuzz_setOperatorPISplitFirstTime(
address operator,
uint16 split
) public filterFuzzedAddressInputs(operator) {
Expand All @@ -615,7 +608,7 @@ contract RewardsCoordinatorUnitTests_setOperatorPISplit is RewardsCoordinatorUni
}

// Testing the split setting for a second time prior to the earlier activation.
function testFuzz_setOperatorAVSSplitSecondTimeBeforePriorActivation(
function testFuzz_Revert_setOperatorPISplitSecondTimeBeforePriorActivation(
address operator,
uint16 firstSplit,
uint16 secondSplit,
Expand All @@ -624,29 +617,22 @@ contract RewardsCoordinatorUnitTests_setOperatorPISplit is RewardsCoordinatorUni
cheats.assume(operator != address(0));
firstSplit = uint16(bound(firstSplit, 0, ONE_HUNDRED_IN_BIPS));
secondSplit = uint16(bound(secondSplit, 0, ONE_HUNDRED_IN_BIPS));
warpTime = uint32(bound(warpTime, uint32(block.timestamp), uint32(block.timestamp) + activationDelay - 1));
uint16 oldSplit = rewardsCoordinator.getOperatorPISplit(operator);
warpTime = uint32(bound(warpTime, uint32(block.timestamp), uint32(block.timestamp) + activationDelay));

// Setting First Split
cheats.prank(operator);
rewardsCoordinator.setOperatorPISplit(operator, firstSplit);
// Warping to time before activation of First split
cheats.warp(warpTime);
uint32 activatedAt = uint32(block.timestamp) + activationDelay;

// Setting Second Split
cheats.expectEmit(true, true, true, true, address(rewardsCoordinator));
emit OperatorPISplitBipsSet(operator, operator, activatedAt, oldSplit, secondSplit);
// Trying to set Second Split
cheats.prank(operator);
cheats.expectRevert("RewardsCoordinator._setOperatorSplit: earlier split not activated yet");
rewardsCoordinator.setOperatorPISplit(operator, secondSplit);

assertEq(oldSplit, rewardsCoordinator.getOperatorPISplit(operator), "Incorrect Operator split");
cheats.warp(activatedAt);
assertEq(secondSplit, rewardsCoordinator.getOperatorPISplit(operator), "Incorrect Operator split");
}

// Testing the split setting for a second time after earlier activation.
function testFuzz_setOperatorAVSSplitSecondTimeAfterPriorActivation(
function testFuzz_setOperatorPISplitSecondTimeAfterPriorActivation(
address operator,
uint16 firstSplit,
uint16 secondSplit,
Expand All @@ -656,7 +642,7 @@ contract RewardsCoordinatorUnitTests_setOperatorPISplit is RewardsCoordinatorUni
firstSplit = uint16(bound(firstSplit, 0, ONE_HUNDRED_IN_BIPS));
secondSplit = uint16(bound(secondSplit, 0, ONE_HUNDRED_IN_BIPS));
warpTime = uint32(
bound(warpTime, uint32(block.timestamp) + activationDelay, type(uint32).max - activationDelay)
bound(warpTime, uint32(block.timestamp) + activationDelay + 1, type(uint32).max - activationDelay)
);

// Setting First Split
Expand Down
Loading