feat: enforce timelocked unpause in emergency killswitch#705
Merged
Baskarayelu merged 1 commit intoMay 30, 2026
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR: feat: enforce timelocked unpause in emergency killswitch
Branch:
feature/killswitch-timelock→mainSummary
Closes #660
Closes #660
This pull request implements the Unpause Timelock safety invariants for the
emergency_killswitchcontract. The mechanism introduces a mandatory cooling-off window during an incident, preventing rapid-cycle state oscillations and accidental premature reactivation of the contract.Changes
emergency_killswitch/src/lib.rs:Error::InvalidSchedule(5) error code.pauseto automatically cancel and remove any pending unpause schedule (DataKey::UnpauseSchedule) to prevent the bypass of cooling-off windows with stale/queued schedules.unpauseto strictly enforceenv.ledger().timestamp() >= scheduled_timeusing the schedule recorded underDataKey::UnpauseSchedule, returningError::InvalidScheduleif no schedule is active, andError::Unauthorizedif called prematurely.schedule_unpauseto reject past-dated schedules (time < env.ledger().timestamp()) withError::InvalidSchedule, ensuring the timelock cannot be bypassed by scheduling in the past.///documentation on the timelock invariants.emergency_killswitch/tests/test_killswitch.rs:test_premature_unpause_rejection: Asserts thatunpausefails before the scheduled time and succeeds exactly at the boundary.test_re_pause_cancels_schedule: Asserts that a newpausecancels any existing schedule, requiring a new schedule to be set.test_timelock_bypass_rejection: Asserts that past-dated unpause schedule timestamps are immediately rejected._unauthorized).emergency_killswitch/THREAT_MODEL.md:schedule_unpause,unpause,is_paused,pause, andDataKey.docs/killswitch-timelock.md:Test Output