Skip to content

Pausable: Allow _pause() when the contract is currently paused #6075

@CarsonCase

Description

@CarsonCase

🧐 Motivation
Currently in the Pausable contract, the docstring states regarding _pause() "The contract must not be paused".
I don't believe this should be an invariant of the pause function. I'll explain why in detail in the next section.

Currently it is not possible to use Pausable to change this, as if you attempt to override _pause() without the whenNotPaused modifier you'll quickly find that _paused is private and you cannot set it to true. Thus meaning that if you are using Pausable you can never pause when the contract is already paused.

📝 Details
But why is this an issue?

Imagine for a moment you have a script that will pull from a database the list of all your companies deployed pausable contracts, and attempt to pause them all in a multicall batch transaction in the event of an emergency. There are hundreds of contracts in this database, and when you see a worrying message from another team member about some on-chain activity you decide to be safe rather than sorry and pause all contracts.
However, somewhere in this database a contract is duplicated. Now because of the duplicated contract address, the entire multicall will fail. As the first pause to this contract will set _paused to true, then the second call will revert with: EnforcedPause.
Now, because of this, you must either find the duplicate contract and remove it, or individually pause contracts, taking significantly more time to react to the situation.

TL;DR : Enforcing that _pause can only be triggered when the contract is not paused can lead to DOS. While this does rely on an error of periphery tools and is not the responsibility of OZ, it's of significant concern for something as important as Pausable, and I think the function should at least have the ability to be overriden.

Thank you for reviewing this issue! I'm curious to hear what the OZ team/community thinks about this as I'm not a security researcher but a humble dev, so any thoughts or opinions on this matter are appreciated!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions