pause(), and it refuses to start if that list is ever widened. Reopening a paused contract always stays with your own owner or multisig — disarming the watch never unpauses anything, and there is no code path here that could. Sentinelleai holds a pauser role on your contract, never ownership or admin rights.What you need before enrolling
- 1
Your contract exposes pause() and paused()
The target must be a Pausable contract (or equivalent): a readablepaused()boolean and apause()function present in the deployed bytecode. - 2
Grant the pause role to the address Sentinelleai shows you
Enrolling generates a dedicated key for that one protocol. Its private key never leaves the platform and is never displayed; only its address is shown, for you to copy and grant the pause role to (isPauseror an OpenZeppelinPAUSER_ROLEgrant). - 3
Fund the pauser address
It needs enough native token on the target chain to cover a handful ofpause()calls — enrolment checks the balance against the current gas price and tells you if it is short. - 4
Keep the pauser separate from your owner and admin
Enrolment refuses a pauser address that is also the contract's owner, or that holds the default admin role — either would let the same key that pauses also unpause, which defeats the whole design.
The six verification checks
Before a protocol can be armed, six read-only checks (V1–V6) must all pass. Every read goes through a live RPC call against the chain you enrolled on; any read that cannot be resolved makes its check "unknown", never rounded up to a pass.
| Check | Question | Passes when | Fails when |
|---|---|---|---|
| V1 | Is this a Pausable contract? | paused() returns a valid boolean | paused() does not return a bool |
| V2 | Is pause() exposed? | The deployed bytecode contains the pause() selector | The selector is absent from the bytecode |
| V3 | Does the pauser hold pause authority? | isPauser() or the pauser role check returns true for the pauser address | Either check answers false — the role has not been granted yet |
| V4 | Is the pauser separated from unpause authority? | The pauser is not the owner and does not hold the default admin role | The pauser is the owner, or holds the default admin role — it could unpause or grant itself the ability to |
| V5 | Is the pauser funded? | Its balance covers at least a few pause() calls at the current gas price | Balance is below that floor |
| V6 | Was a baseline recorded? | A code hash (or EIP-1967 implementation address, for a proxy) was read and stored for every watched address | A baseline could not be read for one or more watched addresses |
A protocol can only be armed once every check reads pass. You can re-run verification at any time from the Auto-pause page.
What triggers a pause, and what does not
Once armed, the engine polls your enrolled contracts roughly every two minutes, reading each check through at least two independent RPC endpoints and only acting when they agree — an endpoint that cannot be reached, or that disagrees with the others, blocks a trigger rather than causing one. A confirmed, agreed signal on any of the following sends pause():
- Ownership escape —
owner()no longer returns the owner recorded when the protocol was enrolled and verified. - Bytecode mutation — the runtime bytecode hash of a watched contract enrolled as immutable code no longer matches its recorded baseline (including the contract's code being destroyed entirely).
- Proxy implementation drift — the EIP-1967 implementation slot of a watched proxy no longer points at the implementation recorded at enrolment.
After a pause
A pause buys time, nothing more. You investigate what happened, and you decide when and how to unpause — Sentinelleai never does either. Every check, trigger, and transaction attempt is recorded as an event, and delivery of the pause transaction itself is tracked the same way any other protective action is: see the evidence ledger for how these events are chained and reported.
A pause also triggers the customer report flow: you get a short email notice as soon as pause() lands, then the full signed report after a hold window, with the consent you signed for Auto-pause attached to it. See Reports sent to you for the notice, the hold, and how an operator can add a note or skip a delivery.
Testnet rehearsal
The enrolment form groups chains into mainnet and testnet. Enrolling a throwaway contract on a testnet first lets you see the full enrol → verify → arm flow, and a real pause, before committing a production contract to the service.

Pricing structure
Auto-pause is billed per protocol per month. One pausable contract, plus the contracts watched around it, on one chain, counts as one protocol — the same protocol deployed on a second chain counts as a second protocol. It is sold as a standalone add-on and is not included in the general bundle, because it is the one function here that can move a money-bearing contract on your behalf, so enrolling it is always an explicit, deliberate choice. See pricing for current figures.
Subscribing requires signing a consent the first time: a phrase you type verbatim confirming you read this page, recorded against your identity in the evidence ledger before checkout proceeds. See Plans & billing for what exactly is recorded.
What it stops short of
- It detects three specific, unambiguous signals — ownership change, bytecode mutation, proxy re-pointing — not exploitation in general.
- It cannot read your contract's business logic and will not stop a hack that operates entirely within it.
- It withholds action rather than guess whenever RPCs disagree or cannot be reached, which trades some missed detections for never pausing on bad information.
- It never unpauses. Reopening is always a decision made by your own owner or multisig.