Emergency Actions
This page describes emergency containment on TokenPool v2.0 pools. Differences for v1.x pools are noted inline.
It covers the emergency actions you can take to contain or halt cross-chain transfers on a specific CCIP lane, using rate limit configuration and related pool controls.
These actions are for incident response, maintenance, or risk containment. Don't use them for routine configuration.
Emergency actions contain operational risk temporarily. Review the underlying cause before you restore normal transfer activity.
When to use emergency actions
You may need to take emergency action if:
- abnormal or unexpected transfer activity is detected
- a misconfiguration or incident is under investigation
- maintenance requires temporarily stopping transfers on a lane
Emergency actions are scoped to a specific token pool and lane (disabling FTF transfers covers every remote chain on the pool). They do not pause CCIP globally.
Rate-limit-based lockdown (rateLimitAdmin or owner)
Preferred: throttle to zero
To block transfers while keeping the limiter enabled, set both inbound and outbound for the affected bucket(s):
Config memory lockdown = Config({
isEnabled: true,
capacity: 0,
rate: 0
});
Submit via setRateLimitConfig (v2.0) or setChainRateLimiterConfig (v1.x). Any positive transfer amount fails because no capacity is available.
Alternative: minimal non-zero values
Because enabled limiters require rate ≤ capacity, you can also use very small non-zero values:
Config memory lockdown = Config({
isEnabled: true,
capacity: 1,
rate: 1
});
This allows at most one base unit of transfer before the bucket is depleted. For 18-decimal tokens, one base unit is negligible; for low-decimal tokens, consider the throttle-to-zero pattern instead.
Update all relevant buckets
For full lane containment, update both directions on both chains and both bucket types if the fast-finality bucket is enabled:
| Chain | Pool | Direction | Buckets to lock |
|---|---|---|---|
| Source | Token pool | Outbound | Default (+ fast-finality on v2.0 if enabled) |
| Destination | Token pool | Inbound | Default (+ fast-finality on v2.0 if enabled) |
Example: v2.0 pool single-bucket lockdown
RateLimitConfigArgs[] memory args = new RateLimitConfigArgs[](1);
args[0] = RateLimitConfigArgs({
remoteChainSelector: REMOTE_SELECTOR,
fastFinality: false,
outboundRateLimiterConfig: Config(true, 0, 0),
inboundRateLimiterConfig: Config(true, 0, 0)
});
tokenPool.setRateLimitConfig(args);
Example: v1.x pool single-lane lockdown
tokenPool.setChainRateLimiterConfig(
REMOTE_SELECTOR,
Config(true, 0, 0), // outbound
Config(true, 0, 0) // inbound
);
Repeat on the counterpart chain with directions reversed. On v2.0, repeat with fastFinality: true if the fast-finality bucket is enabled.
Owner-only emergency actions
These options require the pool owner, not just rateLimitAdmin.
Remove the lane entirely
function applyChainUpdates(
uint64[] calldata remoteChainSelectorsToRemove,
ChainUpdate[] calldata chainsToAdd
) external;
Calling applyChainUpdates with a remote selector in the remove array deletes that chain's remote pools, remote token address, and rate limit state (default and fast-finality buckets) from the pool. This is stronger than throttling and prevents all transfers on the lane until the chain is re-added.
Disable FTF transfers
function setAllowedFinalityConfig(bytes4 allowedFinality) external;
The owner can restrict which finality modes the pool accepts on outbound transfers. Passing 0x00000000 (WAIT_FOR_FINALITY_FLAG, the default) makes the pool reject every outbound FTF transfer without changing default bucket limits. The setting covers every remote chain on the pool.
Important considerations
When locking down a lane:
- partial lockdown (one direction, one chain, or one bucket type) may still allow some traffic
- config changes take effect immediately and refill buckets to full capacity. For lockdown configs with
capacity = 0, full capacity is zero tokens, so transfers remain blocked. - behavior depends on the token's smallest unit when using minimal non-zero values
Use this approach to contain activity, not to permanently disable rate limits.
Restoring normal operation
To resume normal transfers:
- Update inbound and outbound configurations with appropriate capacity and refill values on both chains
- Update both default and fast-finality buckets if you locked both
- Revalidate token units and inspect onchain state before restoring service
- If you removed the lane via
applyChainUpdates, re-add the chain with appropriate initial limits (this sets only the default buckets, so set any fast-finality buckets again withsetRateLimitConfig)
What this page does not cover
This page does not cover:
- routine rate limit tuning (see Common Scenarios)
- worked examples for different token decimals (see Common Scenarios)
- fully removing rate limits with
isEnabled = false(see Common Scenarios)