Skip to main content
The Pausable contract provides an emergency stop mechanism that allows authorized pausers to halt contract operations when necessary. This is a critical security feature for responding to vulnerabilities or attacks. Contract: src/roles/Pausable.sol

Key Concepts

  • Paused State: Boolean flag indicating whether the contract is paused
  • Pauser Role: Authorized address that can pause and unpause the contract
  • whenNotPaused Modifier: Guards functions to prevent execution when paused

State Variables

paused

bool public paused = false
Indicates whether the contract is currently paused. When true, functions with the whenNotPaused modifier cannot be executed. Default: false

Functions

pause

function pause() external onlyPauser
Pauses the contract, preventing execution of functions protected by the whenNotPaused modifier. Requirements:
  • Caller must be the pauser
Effects:
  • Sets paused to true
Emits: Pause() Source: Pausable.sol:64

unpause

function unpause() external onlyPauser
Unpauses the contract, restoring normal operation. Requirements:
  • Caller must be the pauser
Effects:
  • Sets paused to false
Emits: Unpause() Source: Pausable.sol:72

updatePauser

function updatePauser(address _newPauser) external onlyOwner
Updates the pauser role to a new address. Parameters:
  • _newPauser: Address of the new pauser
Requirements:
  • Caller must be the owner
  • New pauser must be non-zero address
Emits: PauserChanged(address indexed newAddress) Source: Pausable.sol:80

pauser

function pauser() external view returns (address)
Returns the current pauser address. Returns: Address of the current pauser Source: Pausable.sol:57

Modifiers

whenNotPaused

modifier whenNotPaused()
Restricts function execution to when the contract is not paused. Reverts: “Pausable: paused” if the contract is currently paused Usage: Apply to functions that should be disabled during emergency pause Source: Pausable.sol:40 Example:
function depositForBurn(
    uint256 amount,
    uint32 destinationDomain,
    bytes32 mintRecipient,
    address burnToken
) external whenNotPaused {
    // Function logic
}

onlyPauser

modifier onlyPauser()
Restricts function access to the pauser only. Reverts: “Pausable: caller is not the pauser” if caller is not the pauser Source: Pausable.sol:48

Events

Pause

event Pause()
Emitted when the contract is paused.

Unpause

event Unpause()
Emitted when the contract is unpaused.

PauserChanged

event PauserChanged(address indexed newAddress)
Emitted when the pauser role is transferred to a new address. Parameters:
  • newAddress: Address of the new pauser

Internal Functions

_updatePauser

function _updatePauser(address _newPauser) internal
Internal function to update the pauser role. Parameters:
  • _newPauser: Address of the new pauser
Requirements:
  • New pauser must be non-zero address
Emits: PauserChanged(address indexed newAddress) Source: Pausable.sol:87

Usage Example

// Pause the contract in case of emergency (as pauser)
pausable.pause();

// Check if contract is paused
bool isPaused = pausable.paused();

// Unpause after issue is resolved
pausable.unpause();

// Transfer pauser role (as owner)
pausable.updatePauser(0x123...);

Integration with CCTP

In CCTP contracts, the whenNotPaused modifier is applied to critical functions:
  • TokenMessenger: depositForBurn(), depositForBurnWithCaller(), replaceDepositForBurn()
  • MessageTransmitter: receiveMessage(), replaceMessage()
When paused, these operations are disabled while administrative functions remain accessible.

Security Considerations

  • The pauser role is separate from the owner role for operational flexibility
  • Only the owner can change the pauser address
  • Pausing is immediate and affects all protected functions
  • The pauser should be a trusted address (e.g., multisig or DAO)
  • Consider implementing monitoring to detect when pause is triggered
  • Ensure the pauser key is highly secure and accessible during emergencies

Origin

Forked from Centre USDC Pausable with modifications:
  • Updated Solidity version from 0.6.12 to 0.7.6
  • Changed pauser visibility to private with external getter
  • Added internal _updatePauser function

Build docs developers (and LLMs) love