A contract refusing to act is not an error, it is an undo. Read OpenZeppelin's Pausable end to end: one boolean, two gates, two named errors, and the four ways of saying no you have now met across five real contracts.
Your fifth contract, and the smallest idea in the course so far. OpenZeppelin's Pausable holds no tokens, moves no value, and owns nothing. Its entire job is to give another contract the ability to refuse, and to make that refusal readable to whoever asked.
One hundred and twelve lines, and the shape will feel familiar within seconds, because it is built exactly like the Ownable you read in week one. What is new is the subject. This lesson is about the moment a contract says no, and what that moment actually does.
Nothing here is new. A licence comment, a release stamp, the caret version that accepts 0.8.20 and anything later in the series, an import naming Context, and an abstract contract built on it. Line for line, this is the opening of Ownable.
That is worth noticing rather than skipping. A whole family of files shares this shape, so once you can read the first six lines of one of them you can read the first six lines of all of them. Move fast here. The interesting part starts at line 18.
One state variable. A `bool`, which holds one of exactly two values, marked `private` so no other Solidity code reaches it directly. Every refusal in this file turns on that single bit, and there is nothing else stored anywhere in it.
Two things follow from the type alone. It starts out `false`, because that is what an unset boolean is, so a fresh contract is not paused. And it can never record who flipped it, or when, because one bit has no room for either fact.
Two events, one for each direction, and both carry an address: the account that did it. The state block could not hold that fact, so the file puts it somewhere else, into the log, where anything watching from outside can read it afterwards.
Hold them against the event you read in Ownable, which marked its addresses `indexed`. These two do not. Indexing makes a field searchable by anything filtering the log, and these two announcements are simply not written that way.
Two custom errors, the same construction you met in Ownable: a named failure type the contract can raise instead of stopping with a message. Notice the empty parentheses. Unlike `OwnableUnauthorizedAccount`, neither of these carries any data at all.
`EnforcedPause` is the obvious one, raised when something is attempted while the contract is paused. The second name is less obvious, and it is worth predicting before you read on.