@@ -288,17 +288,50 @@ contract XanV1VotingTest is Test {
288288 assertEq (endTime, Time.timestamp () + Parameters.DELAY_DURATION);
289289 }
290290
291- function test_scheduleVoterBodyUpgrade_cancels_a_scheduled_upgrade_by_the_council_if_present () public {
291+ function test_scheduleVoterBodyUpgrade_cancels_a_scheduled_upgrade_by_the_council_before_the_delay_has_passed ()
292+ public
293+ {
292294 // Schedule `_OTHER_NEW_IMPL` with the council.
293295 vm.prank (_COUNCIL);
294296 _xanProxy.scheduleCouncilUpgrade (_OTHER_NEW_IMPL);
297+ (, uint48 endTime ) = _xanProxy.scheduledCouncilUpgrade ();
295298
296299 // Vote on `_NEW_IMPL` with the voter body.
297300 vm.startPrank (_defaultSender);
298301 _xanProxy.lock (_xanProxy.totalSupply ());
299302 _xanProxy.castVote (_NEW_IMPL);
300303 vm.stopPrank ();
301304
305+ // Ensure that the delay has NOT passed.
306+ assertLt (Time.timestamp () + 24 hours, endTime);
307+
308+ // Schedule `_NEW_IMPL` with the voter body
309+ vm.expectEmit (address (_xanProxy));
310+ emit IXanV1.VoterBodyUpgradeScheduled (_NEW_IMPL, Time.timestamp () + Parameters.DELAY_DURATION);
311+
312+ vm.expectEmit (address (_xanProxy));
313+ emit IXanV1.CouncilUpgradeVetoed (_OTHER_NEW_IMPL);
314+ _xanProxy.scheduleVoterBodyUpgrade ();
315+ }
316+
317+ function test_scheduleVoterBodyUpgrade_cancels_a_scheduled_upgrade_by_the_council_after_the_delay_has_passed ()
318+ public
319+ {
320+ // Schedule `_OTHER_NEW_IMPL` with the council.
321+ vm.prank (_COUNCIL);
322+ _xanProxy.scheduleCouncilUpgrade (_OTHER_NEW_IMPL);
323+ (, uint48 endTime ) = _xanProxy.scheduledCouncilUpgrade ();
324+
325+ // Vote on `_NEW_IMPL` with the voter body.
326+ vm.startPrank (_defaultSender);
327+ _xanProxy.lock (_xanProxy.totalSupply ());
328+ _xanProxy.castVote (_NEW_IMPL);
329+ vm.stopPrank ();
330+
331+ // Ensure that the delay has just passed.
332+ skip (Parameters.DELAY_DURATION + 1 );
333+ assertGt (Time.timestamp (), endTime);
334+
302335 // Schedule `_NEW_IMPL` with the voter body
303336 vm.expectEmit (address (_xanProxy));
304337 emit IXanV1.VoterBodyUpgradeScheduled (_NEW_IMPL, Time.timestamp () + Parameters.DELAY_DURATION);
@@ -308,6 +341,31 @@ contract XanV1VotingTest is Test {
308341 _xanProxy.scheduleVoterBodyUpgrade ();
309342 }
310343
344+ function test_scheduleVoterBodyUpgrade_cancels_a_scheduled_upgrade_by_the_council_and_resets_the_scheduled_upgrade_to_zero (
345+ ) public {
346+ // Schedule `_OTHER_NEW_IMPL` with the council.
347+ vm.prank (_COUNCIL);
348+ uint48 expectedEndTime = Time.timestamp () + Parameters.DELAY_DURATION;
349+ _xanProxy.scheduleCouncilUpgrade (_OTHER_NEW_IMPL);
350+ (address impl , uint48 endTime ) = _xanProxy.scheduledCouncilUpgrade ();
351+ assertEq (impl, _OTHER_NEW_IMPL);
352+ assertEq (endTime, expectedEndTime);
353+
354+ // Vote on `_NEW_IMPL` with the voter body.
355+ vm.startPrank (_defaultSender);
356+ _xanProxy.lock (_xanProxy.totalSupply ());
357+ _xanProxy.castVote (_NEW_IMPL);
358+ vm.stopPrank ();
359+
360+ // Schedule `_NEW_IMPL` with the voter body
361+ _xanProxy.scheduleVoterBodyUpgrade ();
362+
363+ // Check that the council upgrade has been reset
364+ (impl, endTime) = _xanProxy.scheduledCouncilUpgrade ();
365+ assertEq (impl, address (0 ));
366+ assertEq (endTime, 0 );
367+ }
368+
311369 function test_scheduleVoterBodyUpgrade_emits_the_DelayStarted_event () public {
312370 vm.startPrank (_defaultSender);
313371 _xanProxy.lock (_xanProxy.totalSupply ());
0 commit comments