From 68ccc6dcd2a0804703344b8ceab08d3fbf4ab855 Mon Sep 17 00:00:00 2001 From: Kresh Date: Fri, 4 Oct 2024 12:11:42 +0400 Subject: [PATCH 1/2] fix: cover resolvers' set -> unset -> set cases --- src/contracts/slasher/VetoSlasher.sol | 22 ++++++++++++-------- test/slasher/VetoSlasher.t.sol | 30 ++++++++++++++++++++++++--- 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/src/contracts/slasher/VetoSlasher.sol b/src/contracts/slasher/VetoSlasher.sol index e88b81b8..c49da4c9 100644 --- a/src/contracts/slasher/VetoSlasher.sol +++ b/src/contracts/slasher/VetoSlasher.sol @@ -143,7 +143,7 @@ contract VetoSlasher is BaseSlasher, IVetoSlasher { if ( resolverAt(request.subnetwork, request.captureTimestamp, executeSlashHints.captureResolverHint) != address(0) - && resolverAt(request.subnetwork, Time.timestamp(), executeSlashHints.currentResolverHint) != address(0) + && resolverAt(request.subnetwork, Time.timestamp() - 1, executeSlashHints.currentResolverHint) != address(0) && request.vetoDeadline > Time.timestamp() ) { revert VetoPeriodNotEnded(); @@ -205,7 +205,7 @@ contract VetoSlasher is BaseSlasher, IVetoSlasher { resolverAt(request.subnetwork, request.captureTimestamp, vetoSlashHints.captureResolverHint); if ( captureResolver == address(0) - || resolverAt(request.subnetwork, Time.timestamp(), vetoSlashHints.currentResolverHint) == address(0) + || resolverAt(request.subnetwork, Time.timestamp() - 1, vetoSlashHints.currentResolverHint) == address(0) ) { revert NoResolver(); } @@ -239,13 +239,17 @@ contract VetoSlasher is BaseSlasher, IVetoSlasher { address vault_ = vault; bytes32 subnetwork = (msg.sender).subnetwork(identifier); - uint48 timestamp = resolver(subnetwork, setResolverHints.resolverHint) == address(0) - ? Time.timestamp() - : (IVault(vault_).currentEpochStart() + resolverSetEpochsDelay * IVault(vault_).epochDuration()).toUint48(); - - (, uint48 latestTimestamp,) = _resolver[subnetwork].latestCheckpoint(); - if (latestTimestamp > Time.timestamp()) { - _resolver[subnetwork].pop(); + (bool exists, uint48 latestTimestamp,) = _resolver[subnetwork].latestCheckpoint(); + uint48 timestamp; + if (exists) { + if (latestTimestamp > Time.timestamp()) { + _resolver[subnetwork].pop(); + } + + timestamp = (IVault(vault_).currentEpochStart() + resolverSetEpochsDelay * IVault(vault_).epochDuration()) + .toUint48(); + } else { + timestamp = Time.timestamp(); } _resolver[subnetwork].push(timestamp, uint160(resolver_)); diff --git a/test/slasher/VetoSlasher.t.sol b/test/slasher/VetoSlasher.t.sol index 7274f12d..e92cd2a5 100644 --- a/test/slasher/VetoSlasher.t.sol +++ b/test/slasher/VetoSlasher.t.sol @@ -548,12 +548,36 @@ contract VetoSlasherTest is Test { ); assertEq(slasher.resolver(network.subnetwork(0), ""), resolver1); - _setResolver(network, 0, resolver1, ""); + _setResolver(network, 0, address(0), ""); assertEq( slasher.resolverAt(network.subnetwork(0), uint48(blockTimestamp + 2 * vault.epochDuration()), ""), resolver1 ); assertEq(slasher.resolver(network.subnetwork(0), ""), resolver1); + assertEq( + slasher.resolverAt(network.subnetwork(0), uint48(blockTimestamp + 3 * vault.epochDuration()), ""), + address(0) + ); + + blockTimestamp = blockTimestamp + 3 * vault.epochDuration(); + vm.warp(blockTimestamp); + + assertEq( + slasher.resolverAt(network.subnetwork(0), uint48(blockTimestamp + 3 * vault.epochDuration()), ""), + address(0) + ); + assertEq(slasher.resolver(network.subnetwork(0), ""), address(0)); + + _setResolver(network, 0, resolver1, ""); + + assertEq( + slasher.resolverAt(network.subnetwork(0), uint48(blockTimestamp + 2 * vault.epochDuration()), ""), + address(0) + ); + assertEq( + slasher.resolverAt(network.subnetwork(0), uint48(blockTimestamp + 3 * vault.epochDuration()), ""), resolver1 + ); + assertEq(slasher.resolver(network.subnetwork(0), ""), address(0)); } function test_setResolverRevertNotNetwork(uint48 epochDuration, uint48 vetoDuration) public { @@ -1023,7 +1047,7 @@ contract VetoSlasherTest is Test { _setResolver(alice, 0, address(0), ""); - blockTimestamp = blockTimestamp + 3 * epochDuration; + blockTimestamp = blockTimestamp + 3 * epochDuration + 1; vm.warp(blockTimestamp); uint256 slashAmountReal1 = @@ -1693,7 +1717,7 @@ contract VetoSlasherTest is Test { _setResolver(alice, 0, address(0), ""); - blockTimestamp = blockTimestamp + 3 * epochDuration; + blockTimestamp = blockTimestamp + 3 * epochDuration + 1; vm.warp(blockTimestamp); slashAmount1 = Math.min(slashAmount1, Math.min(depositAmount, Math.min(networkLimit, operatorNetworkLimit1))); From 4274712210bd02912141d048800de22278bbe472 Mon Sep 17 00:00:00 2001 From: Kresh Date: Mon, 14 Oct 2024 22:15:39 +0400 Subject: [PATCH 2/2] fix: adapt hints contracts to new resolvers checks --- src/contracts/hints/SlasherHints.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/contracts/hints/SlasherHints.sol b/src/contracts/hints/SlasherHints.sol index fc446769..11dd4bf7 100644 --- a/src/contracts/hints/SlasherHints.sol +++ b/src/contracts/hints/SlasherHints.sol @@ -193,7 +193,7 @@ contract VetoSlasherHints is Hints, VetoSlasher { uint48 captureTimestamp ) external view returns (bytes memory) { bytes memory captureResolverHint = resolverHint(slasher, subnetwork, captureTimestamp); - bytes memory currentResolverHint = resolverHint(slasher, subnetwork, Time.timestamp()); + bytes memory currentResolverHint = resolverHint(slasher, subnetwork, Time.timestamp() - 1); bytes memory slashableStakeHints = BaseSlasherHints(BASE_SLASHER_HINTS).slashableStakeHints(slasher, subnetwork, operator, captureTimestamp); @@ -214,7 +214,7 @@ contract VetoSlasherHints is Hints, VetoSlasher { uint48 captureTimestamp ) external view returns (bytes memory) { bytes memory captureResolverHint = resolverHint(slasher, subnetwork, captureTimestamp); - bytes memory currentResolverHint = resolverHint(slasher, subnetwork, Time.timestamp()); + bytes memory currentResolverHint = resolverHint(slasher, subnetwork, Time.timestamp() - 1); if (captureResolverHint.length > 0 || currentResolverHint.length > 0) { return abi.encode(