@@ -205,7 +205,7 @@ contract SlashingTest is TestBase {
205205
206206 _setupCommitteeForSlashing (_lifetimeInRounds, _executionDelayInRounds);
207207 address [] memory attesters = rollup.getEpochCommittee (Epoch.wrap (INITIAL_EPOCH));
208- uint96 slashAmount = 20e18 ;
208+ uint96 slashAmount = uint96 (slashingProposer. SLASH_AMOUNT_SMALL ()) ;
209209 SlashRound firstSlashingRound = _createSlashingVotes (slashAmount, attesters.length );
210210
211211 uint256 firstExecutableSlot =
@@ -232,7 +232,7 @@ contract SlashingTest is TestBase {
232232 _lifetimeInRounds = bound (_lifetimeInRounds, _executionDelayInRounds + 1 , 127 ); // Must be < ROUNDABOUT_SIZE
233233
234234 _setupCommitteeForSlashing (_lifetimeInRounds, _executionDelayInRounds);
235- uint96 slashAmount = 20e18 ;
235+ uint96 slashAmount = uint96 (slashingProposer. SLASH_AMOUNT_SMALL ()) ;
236236 SlashRound firstSlashingRound = _createSlashingVotes (slashAmount, COMMITTEE_SIZE);
237237
238238 uint256 firstExecutableSlot =
@@ -275,7 +275,7 @@ contract SlashingTest is TestBase {
275275
276276 _setupCommitteeForSlashing (_lifetimeInRounds, _executionDelayInRounds);
277277 address [] memory attesters = rollup.getEpochCommittee (Epoch.wrap (INITIAL_EPOCH));
278- uint96 slashAmount = 20e18 ;
278+ uint96 slashAmount = uint96 (slashingProposer. SLASH_AMOUNT_SMALL ()) ;
279279 SlashRound firstSlashingRound = _createSlashingVotes (slashAmount, attesters.length );
280280
281281 // For tally slashing, we need to predict the payload address and veto it
@@ -307,6 +307,81 @@ contract SlashingTest is TestBase {
307307 slashingProposer.executeRound (firstSlashingRound, committees);
308308 }
309309
310+ function test_SlashingDisableTimestamp () public {
311+ _setupCommitteeForSlashing ();
312+ address [] memory attesters = rollup.getEpochCommittee (Epoch.wrap (INITIAL_EPOCH));
313+ uint96 slashAmount = uint96 (slashingProposer.SLASH_AMOUNT_SMALL ());
314+ SlashRound firstSlashingRound = _createSlashingVotes (slashAmount, attesters.length );
315+
316+ // Initially slashing should be enabled
317+ assertEq (slasher.isSlashingEnabled (), true , "Slashing should be enabled initially " );
318+
319+ // Disable slashing temporarily
320+ vm.prank (address (slasher.VETOER ()));
321+ slasher.setSlashingEnabled (false );
322+
323+ // Should be disabled now
324+ assertEq (slasher.isSlashingEnabled (), false , "Slashing should be disabled after setting to false " );
325+ uint256 disableDuration = slasher.SLASHING_DISABLE_DURATION ();
326+
327+ // Fast forward time but not past the disable duration (still disabled)
328+ vm.warp (block .timestamp + disableDuration - 10 minutes);
329+ assertEq (slasher.isSlashingEnabled (), false , "Slashing should still be disabled after 30 minutes " );
330+
331+ // Fast forward time beyond the disable duration (should be enabled again)
332+ vm.warp (block .timestamp + disableDuration + 1 minutes);
333+ assertEq (slasher.isSlashingEnabled (), true , "Slashing should be enabled again after disable duration expires " );
334+
335+ // Re-enable manually by calling setSlashingEnabled(true)
336+ vm.prank (address (slasher.VETOER ()));
337+ slasher.setSlashingEnabled (false );
338+ assertEq (slasher.isSlashingEnabled (), false , "Slashing should be disabled again " );
339+
340+ vm.prank (address (slasher.VETOER ()));
341+ slasher.setSlashingEnabled (true );
342+ assertEq (slasher.isSlashingEnabled (), true , "Slashing should be enabled after manual re-enable " );
343+ }
344+
345+ function test_CannotSlashIfDisabled () public {
346+ // Use fixed values for a deterministic test
347+ uint256 _lifetimeInRounds = 5 ;
348+ uint256 _executionDelayInRounds = 1 ;
349+
350+ _setupCommitteeForSlashing (_lifetimeInRounds, _executionDelayInRounds);
351+ address [] memory attesters = rollup.getEpochCommittee (Epoch.wrap (INITIAL_EPOCH));
352+ uint96 slashAmount = uint96 (slashingProposer.SLASH_AMOUNT_SMALL ());
353+ SlashRound firstSlashingRound = _createSlashingVotes (slashAmount, attesters.length );
354+
355+ // Calculate executable slot
356+ uint256 firstExecutableSlot =
357+ (SlashRound.unwrap (firstSlashingRound) + _executionDelayInRounds + 1 ) * slashingProposer.ROUND_SIZE ();
358+
359+ // Setup committees
360+ address [][] memory committees = new address [][](slashingProposer.ROUND_SIZE_IN_EPOCHS ());
361+ for (uint256 i = 0 ; i < committees.length ; i++ ) {
362+ Epoch epochSlashed = slashingProposer.getSlashTargetEpoch (firstSlashingRound, i);
363+ committees[i] = rollup.getEpochCommittee (epochSlashed);
364+ }
365+
366+ // Jump to executable slot
367+ timeCheater.cheat__jumpToSlot (firstExecutableSlot);
368+
369+ // Disable slashing - this should prevent execution for 1 hour
370+ vm.prank (address (slasher.VETOER ()));
371+ slasher.setSlashingEnabled (false );
372+
373+ // Should fail while slashing is disabled
374+ vm.expectRevert (abi.encodeWithSelector (Slasher.Slasher__SlashingDisabled.selector ));
375+ slashingProposer.executeRound (firstSlashingRound, committees);
376+
377+ // Re-enable manually by calling setSlashingEnabled(true)
378+ vm.prank (address (slasher.VETOER ()));
379+ slasher.setSlashingEnabled (true );
380+
381+ // Should now work since slashing was re-enabled
382+ slashingProposer.executeRound (firstSlashingRound, committees);
383+ }
384+
310385 function test_SlashingSmallAmount () public {
311386 _setupCommitteeForSlashing ();
312387 uint256 howManyToSlash = HOW_MANY_SLASHED;
0 commit comments