Slashing and Offenses
Overview
This guide explains how the Aztec network's slashing mechanism works and how your sequencer automatically participates in detecting and voting on validator offenses. You'll learn about the Tally Model of slashing, the types of offenses that are automatically detected, and how to configure your sequencer's slashing behavior.
Prerequisites
Before proceeding, you should:
- Have a running sequencer node (see Sequencer Setup Guide)
- Understand that slashing actions are executed automatically when you propose blocks
- Have the Sentinel enabled if you want to detect inactivity offenses
Understanding the Tally Model of Slashing
The Aztec network uses a consensus-based slashing mechanism where validators vote on individual validator offenses during block proposal.
How Slashing Works
Automatic Detection: Your sequencer runs watchers that continuously monitor the network and automatically detect slashable offenses committed by other validators.
Voting Through Proposals: Time is divided into slashing rounds (typically 128 L2 slots per round). When you propose a block during round N, your sequencer automatically votes on which validators from round N-2 should be slashed. This 2-round offset gives the network time to detect offenses before voting.
Vote Encoding: Votes are encoded as bytes where each validator's vote is represented by 2 bits indicating the slash amount (0-3 slash units). The L1 contract tallies these votes and slashes validators that reach quorum.
Execution: After a round ends, there's an execution delay period (approximately 3 days) during which the slashing vetoer can pause execution if needed. Once the delay passes, anyone can execute the round to apply the slashing.
Slashing Rounds and Offsets
Round 1 (Grace Period): No voting happens
Round 2 (Grace Period): No voting happens
Round 3: Proposers vote on offenses from Round 1 (which are typically forgiven due to grace period)
Round 4: Proposers vote on offenses from Round 2
Round N: Proposers vote on offenses from Round N-2
Key parameters:
- Round Size: 128 L2 slots (approximately 1.28 hours at 36 seconds per slot)
- Slashing Offset: 2 rounds (proposers in round N vote on offenses from round N-2)
- Execution Delay: 28 rounds (~3 days)
- Grace Period: First 128 slots (configurable per node)
Slashing Amounts
The L1 contract defines three fixed slashing tiers that can be configured for different offenses. These amounts are set on L1 deployment and can only be changed via governance.
On the current network, all offenses are currently configured to slash 2,000 tokens (1% of the Activation Threshold - the minimum stake required to join the validator set). With the ejection threshold at 98%, validators can be slashed a maximum of 3 times (totaling 3% of their Activation Threshold) before being automatically ejected from the validator set.
Slashable Offenses
Your sequencer automatically detects and votes to slash the following offenses:
1. Inactivity
What it is: A validator fails to attest to block proposals when selected for committee duty, or fails to propose a block when selected as proposer.
Detection criteria:
- Validator misses more than 20% of attestations (configured via
SLASH_INACTIVITY_TARGET_PERCENTAGE=0.8, which sets a 80% attendance target) - Occurs in 2 or more consecutive epochs where the validator was on the committee (configured via
SLASH_INACTIVITY_CONSECUTIVE_EPOCH_THRESHOLD=2)
Proposed penalty: 1% of stake
Note: Requires the Sentinel to be enabled (SENTINEL_ENABLED=true). The Sentinel tracks attestation and proposal activity for all validators over the configured history period.
2. Valid Epoch Not Proven
What it is: An epoch was not proven within the proof submission window, even though all data was available and the epoch was valid.
Detection criteria:
- An epoch gets pruned (removed from the chain)
- Your node can re-execute all transactions from that epoch
- The state roots match the original epoch (indicating it could have been proven)
Proposed penalty: 0% (disabled for initial deployment)
Responsibility: The entire committee of the pruned epoch is slashed.
3. Data Withholding
What it is: The committee failed to make transaction data publicly available, preventing the epoch from being proven.
Detection criteria:
- An epoch gets pruned
- Your node cannot obtain all the transactions needed to re-execute the epoch
- The data was not propagated to the sequencer set before the proof submission window ended
Proposed penalty: 0% (disabled for initial deployment)
Responsibility: The entire committee from the pruned epoch is slashed for failing to propagate data.
4. Proposed Insufficient Attestations
What it is: A proposer submitted a block to L1 without collecting enough valid committee attestations.
Detection criteria:
- Block published to L1 has fewer than 2/3 + 1 attestations from the committee
- Your node detects this through L1 block validation
Proposed penalty: 1% of stake
5. Proposed Incorrect Attestations
What it is: A proposer submitted a block with invalid signatures or signatures from non-committee members.
Detection criteria:
- Block contains attestations with invalid ECDSA signatures
- Block contains signatures from addresses not in the committee
Proposed penalty: 1% of stake
6. Attested to Descendant of Invalid Block
What it is: A validator attested to a block that builds on top of an invalid block.
Detection criteria:
- A validator attests to block B
- Block B's parent block has invalid or insufficient attestations
- Your node has previously identified the parent as invalid
Proposed penalty: 1% of stake
Note: Validators should only attest to blocks that build on valid chains with proper attestations.
Configuring Your Sequencer for Slashing
The slashing module runs automatically when your sequencer is enabled. You can configure its behavior using environment variables or the node's admin API. Remember to enable the Sentinel if you want to detect inactivity offenses.
Environment Variables
Your sequencer comes pre-configured with default slashing settings. You can optionally override these defaults by setting environment variables before starting your node.
Default configuration:
# Grace period - offenses during the first N slots are not slashed
SLASH_GRACE_PERIOD_L2_SLOTS=128 # Default: first round is grace period
# Inactivity detection (requires SENTINEL_ENABLED=true)
SLASH_INACTIVITY_TARGET_PERCENTAGE=0.8 # 80% - slash if missing >20% attestations
SLASH_INACTIVITY_CONSECUTIVE_EPOCH_THRESHOLD=2 # Must be inactive for 2+ epochs
SLASH_INACTIVITY_PENALTY=2000000000000000000000 # 2000 tokens (1%)
# Sentinel configuration (required for inactivity detection)
SENTINEL_ENABLED=true # Must be true to detect inactivity offenses
SENTINEL_HISTORY_LENGTH_IN_EPOCHS=100 # Track 100 epochs of history
# Epoch prune and data withholding penalties (disabled by default)
SLASH_PRUNE_PENALTY=0 # Set to >0 to enable
SLASH_DATA_WITHHOLDING_PENALTY=0 # Set to >0 to enable
# Invalid attestations and blocks
SLASH_PROPOSE_INVALID_ATTESTATIONS_PENALTY=2000000000000000000000 # 2000 tokens
SLASH_ATTEST_DESCENDANT_OF_INVALID_PENALTY=2000000000000000000000 # 2000 tokens
SLASH_INVALID_BLOCK_PENALTY=2000000000000000000000 # 2000 tokens
# Offense expiration
SLASH_OFFENSE_EXPIRATION_ROUNDS=4 # Offenses older than 4 rounds are dropped
# Execution behavior
SLASH_EXECUTE_ROUNDS_LOOK_BACK=4 # Check 4 rounds back for executable slashing rounds
Runtime Configuration via API
You can update slashing configuration while your node is running using the nodeAdmin_setConfig method:
curl -X POST http://localhost:8880 \
-H 'Content-Type: application/json' \
-d '{
"jsonrpc":"2.0",
"method":"nodeAdmin_setConfig",
"params":[{
"slashInactivityPenalty":"2000000000000000000000",
"slashInactivityTargetPercentage":0.9
}],
"id":1
}'
Excluding Validators from Slashing
You can configure your node to always or never slash specific validators:
# Always slash these validators (regardless of detected offenses)
SLASH_VALIDATORS_ALWAYS=0x1234...,0x5678...
# Never slash these validators (even if offenses are detected)
SLASH_VALIDATORS_NEVER=0xabcd...,0xef01...
Note: Validators in SLASH_VALIDATORS_NEVER take priority. If a validator appears in both lists, they won't be slashed.
Automatic protection: Your own validator addresses (from your keystore) are automatically added to SLASH_VALIDATORS_NEVER unless you set slashSelfAllowed=true via the node admin API.
Verify Your Configuration
Check your current slashing configuration:
curl -X POST http://localhost:8880 \
-H 'Content-Type: application/json' \
-d '{
"jsonrpc":"2.0",
"method":"nodeAdmin_getConfig",
"id":1
}'
Look for fields starting with slash in the response to verify your settings.
How Automatic Slashing Works
Once configured, your sequencer handles slashing automatically:
1. Continuous Offense Detection
Watchers run in the background, monitoring:
- Block attestations via the Sentinel (when enabled)
- Invalid blocks from the P2P network
- Chain prunes and epoch validation
- L1 block data for attestation validation