diff --git a/script/DeployBase.s.sol b/script/DeployBase.s.sol
index 27e47c9b..5fd8868b 100644
--- a/script/DeployBase.s.sol
+++ b/script/DeployBase.s.sol
@@ -189,7 +189,8 @@ abstract contract DeployBase is Script {
                 ),
                 pivotSlot: Slot.wrap(
                     uint64(config.verifierSupportedEpoch * config.slotsPerEpoch)
-                )
+                ),
+                admin: deployer
             });
 
             accounting.initialize({
@@ -259,11 +260,18 @@ abstract contract DeployBase is Script {
                 _avgPerfLeewayBP: config.avgPerfLeewayBP
             });
 
-            address gateSeal = _deployGateSeal();
+            address[] memory sealables = new address[](4);
+            sealables[0] = address(csm);
+            sealables[1] = address(accounting);
+            sealables[2] = address(oracle);
+            sealables[3] = address(verifier);
+            address gateSeal = _deployGateSeal(sealables);
 
             csm.grantRole(csm.PAUSE_ROLE(), gateSeal);
             oracle.grantRole(oracle.PAUSE_ROLE(), gateSeal);
             accounting.grantRole(accounting.PAUSE_ROLE(), gateSeal);
+            verifier.grantRole(verifier.PAUSE_ROLE(), gateSeal);
+
             accounting.grantRole(
                 accounting.SET_BOND_CURVE_ROLE(),
                 config.setResetBondCurveAddress
@@ -291,6 +299,12 @@ abstract contract DeployBase is Script {
             csm.grantRole(csm.DEFAULT_ADMIN_ROLE(), config.aragonAgent);
             csm.revokeRole(csm.DEFAULT_ADMIN_ROLE(), deployer);
 
+            verifier.grantRole(
+                verifier.DEFAULT_ADMIN_ROLE(),
+                config.aragonAgent
+            );
+            verifier.revokeRole(verifier.DEFAULT_ADMIN_ROLE(), deployer);
+
             accounting.grantRole(
                 accounting.DEFAULT_ADMIN_ROLE(),
                 config.aragonAgent
@@ -350,14 +364,12 @@ abstract contract DeployBase is Script {
         return address(proxy);
     }
 
-    function _deployGateSeal() internal returns (address) {
+    function _deployGateSeal(
+        address[] memory sealables
+    ) internal returns (address) {
         IGateSealFactory gateSealFactory = IGateSealFactory(
             config.gateSealFactory
         );
-        address[] memory sealables = new address[](3);
-        sealables[0] = address(csm);
-        sealables[1] = address(accounting);
-        sealables[2] = address(oracle);
 
         address committee = config.sealingCommittee == address(0)
             ? deployer
diff --git a/script/DeployCSVerifierElectra.s.sol b/script/DeployCSVerifierElectra.s.sol
index 254e87ef..3c046a23 100644
--- a/script/DeployCSVerifierElectra.s.sol
+++ b/script/DeployCSVerifierElectra.s.sol
@@ -24,6 +24,7 @@ struct Config {
     Slot firstSupportedSlot;
     Slot pivotSlot;
     uint64 slotsPerEpoch;
+    address admin;
 }
 
 // Check the constants below via `yarn run gindex`.
@@ -63,7 +64,8 @@ abstract contract DeployCSVerifier is Script {
             gIHistoricalSummariesPrev: config.gIHistoricalSummariesPrev,
             gIHistoricalSummariesCurr: config.gIHistoricalSummariesCurr,
             firstSupportedSlot: config.firstSupportedSlot,
-            pivotSlot: config.pivotSlot
+            pivotSlot: config.pivotSlot,
+            admin: config.admin
         });
         console.log("CSVerifier deployed at:", address(verifier));
     }
@@ -82,7 +84,8 @@ contract DeployCSVerifierHolesky is DeployCSVerifier {
             gIHistoricalSummariesPrev: HISTORICAL_SUMMARIES_DENEB,
             gIHistoricalSummariesCurr: HISTORICAL_SUMMARIES_ELECTRA,
             firstSupportedSlot: Slot.wrap(950272), // 269_568 * 32, @see https://github.com/eth-clients/mainnet/blob/main/metadata/config.yaml#L52
-            pivotSlot: Slot.wrap(0) // TODO: Update with Electra slot.
+            pivotSlot: Slot.wrap(0), // TODO: Update with Electra slot.
+            admin: 0xE92329EC7ddB11D25e25b3c21eeBf11f15eB325d // Aragon Agent
         });
     }
 }
@@ -100,7 +103,8 @@ contract DeployCSVerifierMainnet is DeployCSVerifier {
             gIHistoricalSummariesPrev: HISTORICAL_SUMMARIES_DENEB,
             gIHistoricalSummariesCurr: HISTORICAL_SUMMARIES_ELECTRA,
             firstSupportedSlot: Slot.wrap(8626176), // 29_696 * 32, @see https://github.com/eth-clients/holesky/blob/main/metadata/config.yaml#L38
-            pivotSlot: Slot.wrap(0) // TODO: Update with Electra slot.
+            pivotSlot: Slot.wrap(0), // TODO: Update with Electra slot.
+            admin: 0x3e40D73EB977Dc6a537aF587D48316feE66E9C8c // Aragon Agent
         });
     }
 }
diff --git a/script/DeployImplementationsBase.s.sol b/script/DeployImplementationsBase.s.sol
index 642a3be2..4448f875 100644
--- a/script/DeployImplementationsBase.s.sol
+++ b/script/DeployImplementationsBase.s.sol
@@ -80,9 +80,24 @@ abstract contract DeployImplementationsBase is DeployBase {
                 ),
                 pivotSlot: Slot.wrap(
                     uint64(config.verifierSupportedEpoch * config.slotsPerEpoch)
-                )
+                ),
+                admin: deployer
             });
 
+            address[] memory sealables = new address[](4);
+            sealables[0] = address(csm);
+            sealables[1] = address(accounting);
+            sealables[2] = address(oracle);
+            sealables[3] = address(verifier);
+            gateSeal = _deployGateSeal(sealables);
+
+            verifier.grantRole(verifier.PAUSE_ROLE(), address(gateSeal));
+            verifier.grantRole(
+                verifier.DEFAULT_ADMIN_ROLE(),
+                config.aragonAgent
+            );
+            verifier.revokeRole(verifier.DEFAULT_ADMIN_ROLE(), deployer);
+
             JsonObj memory deployJson = Json.newObj();
             deployJson.set("CSModuleImpl", address(csmImpl));
             deployJson.set("CSAccountingImpl", address(accountingImpl));
@@ -91,6 +106,7 @@ abstract contract DeployImplementationsBase is DeployBase {
             deployJson.set("CSVerifier", address(verifier));
             deployJson.set("CSEarlyAdoption", address(earlyAdoption));
             deployJson.set("HashConsensus", address(hashConsensus));
+            deployJson.set("GateSeal", address(gateSeal));
             deployJson.set("git-ref", gitRef);
             vm.writeJson(
                 deployJson.str,
diff --git a/script/fork-helpers/SimulateVote.s.sol b/script/fork-helpers/SimulateVote.s.sol
index a3936389..01e250dc 100644
--- a/script/fork-helpers/SimulateVote.s.sol
+++ b/script/fork-helpers/SimulateVote.s.sol
@@ -8,6 +8,8 @@ import { DeploymentFixtures } from "test/helpers/Fixtures.sol";
 import { IStakingRouter } from "../../src/interfaces/IStakingRouter.sol";
 import { OssifiableProxy } from "../../src/lib/proxy/OssifiableProxy.sol";
 import { CSModule } from "../../src/CSModule.sol";
+import { CSAccounting } from "../../src/CSAccounting.sol";
+import { CSFeeOracle } from "../../src/CSFeeOracle.sol";
 import { IBurner } from "../../src/interfaces/IBurner.sol";
 import { ForkHelpersCommon } from "./Common.sol";
 
@@ -100,10 +102,29 @@ contract SimulateVote is Script, DeploymentFixtures, ForkHelpersCommon {
 
         address admin = _prepareAdmin(deploymentConfig.csm);
         csm = CSModule(deploymentConfig.csm);
+        accounting = CSAccounting(deploymentConfig.accounting);
+        oracle = CSFeeOracle(deploymentConfig.oracle);
 
         vm.startBroadcast(admin);
         csm.revokeRole(csm.VERIFIER_ROLE(), address(deploymentConfig.verifier));
         csm.grantRole(csm.VERIFIER_ROLE(), address(upgradeConfig.verifier));
+
+        csm.revokeRole(csm.PAUSE_ROLE(), address(deploymentConfig.gateSeal));
+        accounting.revokeRole(
+            accounting.PAUSE_ROLE(),
+            address(deploymentConfig.gateSeal)
+        );
+        oracle.revokeRole(
+            oracle.PAUSE_ROLE(),
+            address(deploymentConfig.gateSeal)
+        );
+
+        csm.grantRole(csm.PAUSE_ROLE(), address(upgradeConfig.gateSeal));
+        accounting.grantRole(
+            accounting.PAUSE_ROLE(),
+            address(upgradeConfig.gateSeal)
+        );
+        oracle.grantRole(oracle.PAUSE_ROLE(), address(upgradeConfig.gateSeal));
         vm.stopBroadcast();
     }
 }
diff --git a/src/CSVerifier.sol b/src/CSVerifier.sol
index 4ce50582..5a3d3788 100644
--- a/src/CSVerifier.sol
+++ b/src/CSVerifier.sol
@@ -5,6 +5,8 @@ pragma solidity 0.8.24;
 
 import { ICSVerifier } from "./interfaces/ICSVerifier.sol";
 import { ICSModule } from "./interfaces/ICSModule.sol";
+import { AccessControlEnumerable } from "@openzeppelin/contracts/access/extensions/AccessControlEnumerable.sol";
+import { PausableUntil } from "./lib/utils/PausableUntil.sol";
 
 import { BeaconBlockHeader, Slot, Validator, Withdrawal } from "./lib/Types.sol";
 import { GIndex } from "./lib/GIndex.sol";
@@ -22,13 +24,16 @@ function gweiToWei(uint64 amount) pure returns (uint256) {
     return uint256(amount) * 1 gwei;
 }
 
-contract CSVerifier is ICSVerifier {
+contract CSVerifier is ICSVerifier, AccessControlEnumerable, PausableUntil {
     using { amountWei } for Withdrawal;
 
     using SSZ for BeaconBlockHeader;
     using SSZ for Withdrawal;
     using SSZ for Validator;
 
+    bytes32 public constant PAUSE_ROLE = keccak256("PAUSE_ROLE");
+    bytes32 public constant RESUME_ROLE = keccak256("RESUME_ROLE");
+
     // See `BEACON_ROOTS_ADDRESS` constant in the EIP-4788.
     address public constant BEACON_ROOTS =
         0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02;
@@ -77,10 +82,12 @@ contract CSVerifier is ICSVerifier {
         GIndex gIHistoricalSummariesPrev,
         GIndex gIHistoricalSummariesCurr,
         Slot firstSupportedSlot,
-        Slot pivotSlot
+        Slot pivotSlot,
+        address admin
     ) {
         if (withdrawalAddress == address(0)) revert ZeroWithdrawalAddress();
         if (module == address(0)) revert ZeroModuleAddress();
+        if (admin == address(0)) revert ZeroAdminAddress();
 
         if (slotsPerEpoch == 0) revert InvalidChainConfig();
         if (firstSupportedSlot > pivotSlot) revert InvalidPivotSlot();
@@ -101,6 +108,18 @@ contract CSVerifier is ICSVerifier {
 
         FIRST_SUPPORTED_SLOT = firstSupportedSlot;
         PIVOT_SLOT = pivotSlot;
+
+        _grantRole(DEFAULT_ADMIN_ROLE, admin);
+    }
+
+    /// @inheritdoc ICSVerifier
+    function resume() external onlyRole(RESUME_ROLE) {
+        _resume();
+    }
+
+    /// @inheritdoc ICSVerifier
+    function pauseFor(uint256 duration) external onlyRole(PAUSE_ROLE) {
+        _pauseFor(duration);
     }
 
     /// @inheritdoc ICSVerifier
@@ -109,7 +128,7 @@ contract CSVerifier is ICSVerifier {
         WithdrawalWitness calldata witness,
         uint256 nodeOperatorId,
         uint256 keyIndex
-    ) external {
+    ) external whenResumed {
         if (beaconBlock.header.slot < FIRST_SUPPORTED_SLOT) {
             revert UnsupportedSlot(beaconBlock.header.slot);
         }
@@ -151,7 +170,7 @@ contract CSVerifier is ICSVerifier {
         WithdrawalWitness calldata witness,
         uint256 nodeOperatorId,
         uint256 keyIndex
-    ) external {
+    ) external whenResumed {
         if (beaconBlock.header.slot < FIRST_SUPPORTED_SLOT) {
             revert UnsupportedSlot(beaconBlock.header.slot);
         }
diff --git a/src/interfaces/ICSVerifier.sol b/src/interfaces/ICSVerifier.sol
index 8412d7c4..0fb8fcc9 100644
--- a/src/interfaces/ICSVerifier.sol
+++ b/src/interfaces/ICSVerifier.sol
@@ -61,8 +61,13 @@ interface ICSVerifier {
     error UnsupportedSlot(Slot slot);
     error ZeroModuleAddress();
     error ZeroWithdrawalAddress();
+    error ZeroAdminAddress();
     error InvalidPivotSlot();
 
+    function PAUSE_ROLE() external view returns (bytes32);
+
+    function RESUME_ROLE() external view returns (bytes32);
+
     function BEACON_ROOTS() external view returns (address);
 
     function SLOTS_PER_EPOCH() external view returns (uint64);
@@ -87,6 +92,13 @@ interface ICSVerifier {
 
     function MODULE() external view returns (ICSModule);
 
+    /// @notice Pause write methods calls for `duration` seconds
+    /// @param duration Duration of the pause in seconds
+    function pauseFor(uint256 duration) external;
+
+    /// @notice Resume write methods calls
+    function resume() external;
+
     /// @notice Verify withdrawal proof and report withdrawal to the module for valid proofs
     /// @param beaconBlock Beacon block header
     /// @param witness Withdrawal witness against the `beaconBlock`'s state root.
diff --git a/test/CSVerifier.t.sol b/test/CSVerifier.t.sol
index ead089fa..418af3b3 100644
--- a/test/CSVerifier.t.sol
+++ b/test/CSVerifier.t.sol
@@ -7,6 +7,7 @@ import { stdJson } from "forge-std/StdJson.sol";
 
 import { ICSVerifier } from "../src/interfaces/ICSVerifier.sol";
 import { ICSModule } from "../src/interfaces/ICSModule.sol";
+import { PausableUntil } from "../src/lib/utils/PausableUntil.sol";
 import { Initializable } from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
 
 import { CSVerifier } from "../src/CSVerifier.sol";
@@ -38,6 +39,11 @@ contract CSVerifierTestBase is Test, Utilities {
     CSVerifier public verifier;
     Stub public module;
     Slot public firstSupportedSlot;
+    address public admin;
+    address public stranger;
+
+    bytes32 public pauseRole;
+    bytes32 public resumeRole;
 
     string internal fixturesPath = "./test/fixtures/CSVerifier/";
 
@@ -54,6 +60,7 @@ contract CSVerifierTestConstructor is CSVerifierTestBase {
     function setUp() public {
         module = new Stub();
         firstSupportedSlot = Slot.wrap(100_500);
+        admin = nextAddress("ADMIN");
     }
 
     function test_constructor() public {
@@ -70,7 +77,8 @@ contract CSVerifierTestConstructor is CSVerifierTestBase {
             gIFirstValidatorPrev: pack(0x560000000000, 40),
             gIFirstValidatorCurr: pack(0x560000000001, 40),
             firstSupportedSlot: firstSupportedSlot,
-            pivotSlot: Slot.wrap(100_501)
+            pivotSlot: Slot.wrap(100_501),
+            admin: admin
         });
 
         assertEq(address(verifier.WITHDRAWAL_ADDRESS()), withdrawalAddress);
@@ -123,7 +131,8 @@ contract CSVerifierTestConstructor is CSVerifierTestBase {
             gIFirstValidatorPrev: pack(0x560000000000, 40),
             gIFirstValidatorCurr: pack(0x560000000000, 40),
             firstSupportedSlot: firstSupportedSlot, // Any value less than the slots from the fixtures.
-            pivotSlot: firstSupportedSlot
+            pivotSlot: firstSupportedSlot,
+            admin: admin
         });
     }
 
@@ -140,7 +149,8 @@ contract CSVerifierTestConstructor is CSVerifierTestBase {
             gIFirstValidatorPrev: pack(0x560000000000, 40),
             gIFirstValidatorCurr: pack(0x560000000000, 40),
             firstSupportedSlot: firstSupportedSlot, // Any value less than the slots from the fixtures.
-            pivotSlot: firstSupportedSlot
+            pivotSlot: firstSupportedSlot,
+            admin: admin
         });
     }
 
@@ -157,7 +167,26 @@ contract CSVerifierTestConstructor is CSVerifierTestBase {
             gIFirstValidatorPrev: pack(0x560000000000, 40),
             gIFirstValidatorCurr: pack(0x560000000000, 40),
             firstSupportedSlot: firstSupportedSlot, // Any value less than the slots from the fixtures.
-            pivotSlot: firstSupportedSlot
+            pivotSlot: firstSupportedSlot,
+            admin: admin
+        });
+    }
+
+    function test_constructor_RevertWhen_ZeroAdminAddress() public {
+        vm.expectRevert(ICSVerifier.ZeroAdminAddress.selector);
+        verifier = new CSVerifier({
+            withdrawalAddress: nextAddress(),
+            module: address(module),
+            slotsPerEpoch: 32,
+            gIHistoricalSummariesPrev: pack(0x0, 0), // We don't care of the value for this test.
+            gIHistoricalSummariesCurr: pack(0x0, 0), // We don't care of the value for this test.
+            gIFirstWithdrawalPrev: pack(0xe1c0, 4),
+            gIFirstWithdrawalCurr: pack(0xe1c0, 4),
+            gIFirstValidatorPrev: pack(0x560000000000, 40),
+            gIFirstValidatorCurr: pack(0x560000000000, 40),
+            firstSupportedSlot: firstSupportedSlot, // Any value less than the slots from the fixtures.
+            pivotSlot: firstSupportedSlot,
+            admin: address(0)
         });
     }
 }
@@ -165,6 +194,7 @@ contract CSVerifierTestConstructor is CSVerifierTestBase {
 contract CSVerifierWithdrawalTest is CSVerifierTestBase {
     function setUp() public {
         module = new Stub();
+        admin = nextAddress("ADMIN");
 
         verifier = new CSVerifier({
             withdrawalAddress: 0xb3E29C46Ee1745724417C0C51Eb2351A1C01cF36,
@@ -177,8 +207,17 @@ contract CSVerifierWithdrawalTest is CSVerifierTestBase {
             gIFirstValidatorPrev: pack(0x560000000000, 40),
             gIFirstValidatorCurr: pack(0x560000000000, 40),
             firstSupportedSlot: Slot.wrap(100_500), // Any value less than the slots from the fixtures.
-            pivotSlot: Slot.wrap(100_500)
+            pivotSlot: Slot.wrap(100_500),
+            admin: admin
         });
+
+        pauseRole = verifier.PAUSE_ROLE();
+        resumeRole = verifier.RESUME_ROLE();
+
+        vm.startPrank(admin);
+        verifier.grantRole(pauseRole, admin);
+        verifier.grantRole(resumeRole, admin);
+        vm.stopPrank();
     }
 
     function test_processWithdrawalProof() public {
@@ -378,6 +417,27 @@ contract CSVerifierWithdrawalTest is CSVerifierTestBase {
         );
     }
 
+    function test_processWithdrawalProof_RevertWhenPaused() public {
+        WithdrawalFixture memory fixture = abi.decode(
+            _readFixture("withdrawal.json"),
+            (WithdrawalFixture)
+        );
+
+        _setMocksWithdrawal(fixture);
+
+        vm.prank(admin);
+        verifier.pauseFor(100_500);
+        assertTrue(verifier.isPaused());
+
+        vm.expectRevert(PausableUntil.ResumedExpected.selector);
+        verifier.processWithdrawalProof(
+            fixture.beaconBlock,
+            fixture.witness,
+            0,
+            0
+        );
+    }
+
     function _setMocksWithdrawal(WithdrawalFixture memory fixture) internal {
         vm.mockCall(
             verifier.BEACON_ROOTS(),
@@ -398,3 +458,83 @@ contract CSVerifierWithdrawalTest is CSVerifierTestBase {
         );
     }
 }
+
+contract CSVerifierPauseTest is CSVerifierTestBase {
+    function setUp() public {
+        module = new Stub();
+        admin = nextAddress("ADMIN");
+        stranger = nextAddress("STRANGER");
+
+        verifier = new CSVerifier({
+            withdrawalAddress: 0xb3E29C46Ee1745724417C0C51Eb2351A1C01cF36,
+            module: address(module),
+            slotsPerEpoch: 32,
+            gIHistoricalSummariesPrev: pack(0x0, 0), // We don't care of the value for this test.
+            gIHistoricalSummariesCurr: pack(0x0, 0), // We don't care of the value for this test.
+            gIFirstWithdrawalPrev: pack(0xe1c0, 4),
+            gIFirstWithdrawalCurr: pack(0xe1c0, 4),
+            gIFirstValidatorPrev: pack(0x560000000000, 40),
+            gIFirstValidatorCurr: pack(0x560000000000, 40),
+            firstSupportedSlot: Slot.wrap(100_500), // Any value less than the slots from the fixtures.
+            pivotSlot: Slot.wrap(100_500),
+            admin: admin
+        });
+
+        pauseRole = verifier.PAUSE_ROLE();
+        resumeRole = verifier.RESUME_ROLE();
+
+        vm.startPrank(admin);
+        verifier.grantRole(pauseRole, admin);
+        verifier.grantRole(resumeRole, admin);
+        vm.stopPrank();
+    }
+
+    function test_pause() public {
+        assertFalse(verifier.isPaused());
+        vm.prank(admin);
+        verifier.pauseFor(100_500);
+        assertTrue(verifier.isPaused());
+    }
+
+    function test_pause_RevertWhenNoRole() public {
+        expectRoleRevert(stranger, pauseRole);
+        vm.prank(stranger);
+        verifier.pauseFor(100_500);
+    }
+
+    function test_pause_RevertWhenPaused() public {
+        vm.prank(admin);
+        verifier.pauseFor(100_500);
+        assertTrue(verifier.isPaused());
+
+        vm.expectRevert(PausableUntil.ResumedExpected.selector);
+        vm.prank(admin);
+        verifier.pauseFor(100_500);
+    }
+
+    function test_resume() public {
+        vm.prank(admin);
+        verifier.pauseFor(100_500);
+        assertTrue(verifier.isPaused());
+
+        vm.prank(admin);
+        verifier.resume();
+        assertFalse(verifier.isPaused());
+    }
+
+    function test_resume_RevertWhenNoRole() public {
+        vm.prank(admin);
+        verifier.pauseFor(100_500);
+        assertTrue(verifier.isPaused());
+
+        expectRoleRevert(stranger, resumeRole);
+        vm.prank(stranger);
+        verifier.resume();
+    }
+
+    function test_resume_RevertWhenNotPaused() public {
+        vm.expectRevert(PausableUntil.PausedExpected.selector);
+        vm.prank(admin);
+        verifier.resume();
+    }
+}
diff --git a/test/CSVerifierHistorical.t.sol b/test/CSVerifierHistorical.t.sol
index 97920ecd..c309b832 100644
--- a/test/CSVerifierHistorical.t.sol
+++ b/test/CSVerifierHistorical.t.sol
@@ -7,7 +7,7 @@ import { stdJson } from "forge-std/StdJson.sol";
 
 import { ICSVerifier } from "../src/interfaces/ICSVerifier.sol";
 import { ICSModule } from "../src/interfaces/ICSModule.sol";
-
+import { PausableUntil } from "../src/lib/utils/PausableUntil.sol";
 import { GIndex } from "../src/lib/GIndex.sol";
 
 import { CSVerifier } from "../src/CSVerifier.sol";
@@ -15,6 +15,7 @@ import { ICSVerifier } from "../src/interfaces/ICSVerifier.sol";
 import { pack } from "../src/lib/GIndex.sol";
 import { Slot } from "../src/lib/Types.sol";
 
+import { Utilities } from "./helpers/Utilities.sol";
 import { Stub } from "./helpers/mocks/Stub.sol";
 
 function dec(Slot self) pure returns (Slot slot) {
@@ -25,7 +26,7 @@ function dec(Slot self) pure returns (Slot slot) {
 
 using { dec } for Slot;
 
-contract CSVerifierHistoricalTest is Test {
+contract CSVerifierHistoricalTest is Test, Utilities {
     using stdJson for string;
 
     struct HistoricalWithdrawalFixture {
@@ -38,11 +39,16 @@ contract CSVerifierHistoricalTest is Test {
 
     CSVerifier public verifier;
     Stub public module;
+    address public admin;
+
+    bytes32 public pauseRole;
+    bytes32 public resumeRole;
 
     HistoricalWithdrawalFixture public fixture;
 
     function setUp() public {
         module = new Stub();
+        admin = nextAddress("ADMIN");
         verifier = new CSVerifier({
             withdrawalAddress: 0xb3E29C46Ee1745724417C0C51Eb2351A1C01cF36,
             module: address(module),
@@ -54,8 +60,17 @@ contract CSVerifierHistoricalTest is Test {
             gIFirstValidatorPrev: pack(0x560000000000, 40),
             gIFirstValidatorCurr: pack(0x560000000000, 40),
             firstSupportedSlot: Slot.wrap(100_500), // Any value less than the slots from the fixtures.
-            pivotSlot: Slot.wrap(100_500)
+            pivotSlot: Slot.wrap(100_500),
+            admin: admin
         });
+
+        pauseRole = verifier.PAUSE_ROLE();
+        resumeRole = verifier.RESUME_ROLE();
+
+        vm.startPrank(admin);
+        verifier.grantRole(pauseRole, admin);
+        verifier.grantRole(resumeRole, admin);
+        vm.stopPrank();
     }
 
     function _get_fixture() internal {
@@ -171,6 +186,25 @@ contract CSVerifierHistoricalTest is Test {
         );
     }
 
+    function test_processWithdrawalProof_RevertWhenPaused() public {
+        _get_fixture();
+        _setMocksWithdrawal(fixture);
+
+        vm.prank(admin);
+        verifier.pauseFor(100_500);
+        assertTrue(verifier.isPaused());
+
+        vm.expectRevert(PausableUntil.ResumedExpected.selector);
+        // solhint-disable-next-line func-named-parameters
+        verifier.processHistoricalWithdrawalProof(
+            fixture.beaconBlock,
+            fixture.oldBlock,
+            fixture.witness,
+            0,
+            0
+        );
+    }
+
     function _setMocksWithdrawal(
         HistoricalWithdrawalFixture memory _fixture
     ) internal {
diff --git a/test/CSVerifierHistoricalCrossForks.t.sol b/test/CSVerifierHistoricalCrossForks.t.sol
index b6f9b9f2..7c01aed6 100644
--- a/test/CSVerifierHistoricalCrossForks.t.sol
+++ b/test/CSVerifierHistoricalCrossForks.t.sol
@@ -29,9 +29,11 @@ contract CSVerifierBiForkTestConstructor is Test, Utilities {
     CSVerifier verifier;
 
     Stub module;
+    address public admin;
 
     function setUp() public {
         module = new Stub();
+        admin = nextAddress("ADMIN");
     }
 
     function test_constructor_HappyPath() public {
@@ -46,7 +48,8 @@ contract CSVerifierBiForkTestConstructor is Test, Utilities {
             gIHistoricalSummariesPrev: pack(0x3b, 0),
             gIHistoricalSummariesCurr: pack(0x3b, 0),
             firstSupportedSlot: Slot.wrap(8_192),
-            pivotSlot: Slot.wrap(950_272)
+            pivotSlot: Slot.wrap(950_272),
+            admin: admin
         });
 
         assertEq(
@@ -102,7 +105,8 @@ contract CSVerifierBiForkTestConstructor is Test, Utilities {
             gIHistoricalSummariesPrev: pack(0x3b, 0),
             gIHistoricalSummariesCurr: pack(0x3b, 0),
             firstSupportedSlot: Slot.wrap(8_192),
-            pivotSlot: Slot.wrap(950_272)
+            pivotSlot: Slot.wrap(950_272),
+            admin: admin
         });
     }
 
@@ -119,7 +123,8 @@ contract CSVerifierBiForkTestConstructor is Test, Utilities {
             gIHistoricalSummariesPrev: pack(0x3b, 0),
             gIHistoricalSummariesCurr: pack(0x3b, 0),
             firstSupportedSlot: Slot.wrap(8_192),
-            pivotSlot: Slot.wrap(950_272)
+            pivotSlot: Slot.wrap(950_272),
+            admin: admin
         });
     }
 
@@ -136,7 +141,8 @@ contract CSVerifierBiForkTestConstructor is Test, Utilities {
             gIHistoricalSummariesPrev: pack(0x3b, 0),
             gIHistoricalSummariesCurr: pack(0x3b, 0),
             firstSupportedSlot: Slot.wrap(8_192),
-            pivotSlot: Slot.wrap(950_272)
+            pivotSlot: Slot.wrap(950_272),
+            admin: admin
         });
     }
 
@@ -153,12 +159,13 @@ contract CSVerifierBiForkTestConstructor is Test, Utilities {
             gIHistoricalSummariesPrev: pack(0x3b, 0),
             gIHistoricalSummariesCurr: pack(0x3b, 0),
             firstSupportedSlot: Slot.wrap(200),
-            pivotSlot: Slot.wrap(100)
+            pivotSlot: Slot.wrap(100),
+            admin: admin
         });
     }
 }
 
-contract CSVerifierBiForkHistoricalTest is Test {
+contract CSVerifierBiForkHistoricalTest is Test, Utilities {
     using stdJson for string;
 
     struct HistoricalWithdrawalFixture {
@@ -171,11 +178,13 @@ contract CSVerifierBiForkHistoricalTest is Test {
 
     CSVerifier public verifier;
     Stub public module;
+    address public admin;
 
     HistoricalWithdrawalFixture public fixture;
 
     function setUp() public {
         module = new Stub();
+        admin = nextAddress("ADMIN");
         verifier = new CSVerifier({
             withdrawalAddress: 0xb3E29C46Ee1745724417C0C51Eb2351A1C01cF36,
             module: address(module),
@@ -187,7 +196,8 @@ contract CSVerifierBiForkHistoricalTest is Test {
             gIHistoricalSummariesPrev: pack(0x3b, 0),
             gIHistoricalSummariesCurr: pack(0x3b, 0),
             firstSupportedSlot: Slot.wrap(8_192),
-            pivotSlot: Slot.wrap(950_272)
+            pivotSlot: Slot.wrap(950_272),
+            admin: admin
         });
     }
 
diff --git a/test/fork/deployment/PostDeployment.t.sol b/test/fork/deployment/PostDeployment.t.sol
index 398461c8..7531543f 100644
--- a/test/fork/deployment/PostDeployment.t.sol
+++ b/test/fork/deployment/PostDeployment.t.sol
@@ -516,4 +516,10 @@ contract CSVerifierDeploymentTest is Test, Utilities, DeploymentFixtures {
             deployParams.verifierSupportedEpoch * deployParams.slotsPerEpoch
         );
     }
+
+    function test_roles() public {
+        assertTrue(verifier.hasRole(verifier.PAUSE_ROLE(), address(gateSeal)));
+        assertEq(verifier.getRoleMemberCount(verifier.PAUSE_ROLE()), 1);
+        assertEq(verifier.getRoleMemberCount(verifier.RESUME_ROLE()), 0);
+    }
 }
diff --git a/test/fork/integration/GateSeal.t.sol b/test/fork/integration/GateSeal.t.sol
index bbf445e8..677ff2ea 100644
--- a/test/fork/integration/GateSeal.t.sol
+++ b/test/fork/integration/GateSeal.t.sol
@@ -23,10 +23,11 @@ contract GateSealTest is Test, Utilities, DeploymentFixtures {
     }
 
     function test_sealAll() public {
-        address[] memory sealables = new address[](3);
+        address[] memory sealables = new address[](4);
         sealables[0] = address(csm);
         sealables[1] = address(accounting);
         sealables[2] = address(oracle);
+        sealables[3] = address(verifier);
 
         vm.prank(gateSeal.get_sealing_committee());
         gateSeal.seal(sealables);
@@ -34,6 +35,7 @@ contract GateSealTest is Test, Utilities, DeploymentFixtures {
         assertTrue(csm.isPaused());
         assertTrue(accounting.isPaused());
         assertTrue(oracle.isPaused());
+        assertTrue(verifier.isPaused());
     }
 
     function test_sealCSM() public {
@@ -44,6 +46,8 @@ contract GateSealTest is Test, Utilities, DeploymentFixtures {
 
         assertTrue(csm.isPaused());
         assertFalse(accounting.isPaused());
+        assertFalse(oracle.isPaused());
+        assertFalse(verifier.isPaused());
     }
 
     function test_sealAccounting() public {
@@ -54,6 +58,8 @@ contract GateSealTest is Test, Utilities, DeploymentFixtures {
 
         assertTrue(accounting.isPaused());
         assertFalse(csm.isPaused());
+        assertFalse(oracle.isPaused());
+        assertFalse(verifier.isPaused());
     }
 
     function test_sealOracle() public {
@@ -63,7 +69,20 @@ contract GateSealTest is Test, Utilities, DeploymentFixtures {
         gateSeal.seal(sealables);
 
         assertTrue(oracle.isPaused());
+        assertFalse(csm.isPaused());
         assertFalse(accounting.isPaused());
+        assertFalse(verifier.isPaused());
+    }
+
+    function test_sealVerifier() public {
+        address[] memory sealables = new address[](1);
+        sealables[0] = address(verifier);
+        vm.prank(gateSeal.get_sealing_committee());
+        gateSeal.seal(sealables);
+
+        assertTrue(verifier.isPaused());
         assertFalse(csm.isPaused());
+        assertFalse(accounting.isPaused());
+        assertFalse(oracle.isPaused());
     }
 }
diff --git a/test/fork/invariant/Invariants.t.sol b/test/fork/invariant/Invariants.t.sol
index 11775292..f7d55487 100644
--- a/test/fork/invariant/Invariants.t.sol
+++ b/test/fork/invariant/Invariants.t.sol
@@ -226,3 +226,23 @@ contract HashConsensusInvariant is InvariantsBase {
         );
     }
 }
+
+contract VerifierInvariant is InvariantsBase {
+    function test_roles() public {
+        assertEq(
+            verifier.getRoleMemberCount(verifier.PAUSE_ROLE()),
+            1,
+            "pause"
+        );
+        assertEq(
+            verifier.getRoleMember(verifier.PAUSE_ROLE(), 0),
+            address(gateSeal),
+            "pause address"
+        );
+        assertEq(
+            verifier.getRoleMemberCount(verifier.RESUME_ROLE()),
+            0,
+            "resume"
+        );
+    }
+}
diff --git a/test/fork/voting/StatePostVote.t.sol b/test/fork/voting/StatePostVote.t.sol
index 5f9d7003..a2ac894b 100644
--- a/test/fork/voting/StatePostVote.t.sol
+++ b/test/fork/voting/StatePostVote.t.sol
@@ -258,4 +258,10 @@ contract ContractsStateTest is Test, Utilities, DeploymentFixtures {
             0
         );
     }
+
+    function test_verifier_roles() public {
+        assertTrue(verifier.hasRole(verifier.PAUSE_ROLE(), address(gateSeal)));
+        assertEq(verifier.getRoleMemberCount(verifier.PAUSE_ROLE()), 1);
+        assertEq(verifier.getRoleMemberCount(verifier.RESUME_ROLE()), 0);
+    }
 }
diff --git a/test/helpers/Fixtures.sol b/test/helpers/Fixtures.sol
index e74fc468..48c71766 100644
--- a/test/helpers/Fixtures.sol
+++ b/test/helpers/Fixtures.sol
@@ -104,6 +104,7 @@ contract DeploymentHelpers is Test {
         address verifier;
         address earlyAdoption;
         address hashConsensus;
+        address gateSeal;
     }
 
     function envVars() public returns (Env memory) {
@@ -190,6 +191,7 @@ contract DeploymentHelpers is Test {
             config,
             ".HashConsensus"
         );
+        upgradeConfig.gateSeal = vm.parseJsonAddress(config, ".GateSeal");
     }
 
     function parseDeployParams(
@@ -251,6 +253,7 @@ contract DeploymentFixtures is StdCheats, DeploymentHelpers {
             earlyAdoption = CSEarlyAdoption(upgradeConfig.earlyAdoption);
             verifier = CSVerifier(upgradeConfig.verifier);
             hashConsensus = HashConsensus(upgradeConfig.hashConsensus);
+            gateSeal = IGateSeal(upgradeConfig.gateSeal);
         }
     }