Skip to content
LogoLogo

Slashing

Read Learn first

Slashing is a penalty mechanism that deters operators from breaking their commitments. Violations include failing to complete tasks properly or accurately. Slashing typically burns or redistributes the operator's staked funds.

Slasher Module

Each Symbiotic Vault has an immutably set Slasher module implementation. There are three possible implementation choices:

  1. No Slasher - no slashing can occur within the Vault

  2. Instant Slasher (TYPE = 0) - allows networks to immediately slash funds in a FIFO order

  3. Veto Slasher (TYPE = 1) - supports a veto process over a pre-defined veto period, where designated Resolvers can cancel the slashing request

Each Slasher module contains a slashableStake(subnetwork, operator, captureTimestamp, hints) function that returns the amount of collateral still slashable for the given captureTimestamp at the current moment.

Slashing Guarantees

Each Symbiotic Vault has an epoch duration (obtained via Vault.epochDuration()), which determines the withdrawal delay and provides a period during which slashing guarantees are held.

The following inequality must hold:

executeSlashTimestamp - captureTimestamp <= epochDuration

Slasher (Type 0)

The slasher instantly executes slashing requests when received and validated.

NetworkSlasher.sol
import {IVault} from "@symbioticfi/core/src/interfaces/vault/IVault.sol";
import {ISlasher} from "@symbioticfi/core/src/interfaces/slasher/ISlasher.sol";
import {Subnetwork} from "@symbioticfi/core/src/contracts/libraries/Subnetwork.sol";
 
address slasher = IVault(vault).slasher();
bytes32 subnetwork = Subnetwork.subnetwork(NETWORK, IDENTIFIER);
ISlasher(slasher).slash(
    subnetwork,
    operator,
    amount,
    captureTimestamp,
    hints
)

Parameters:

  • subnetwork - full identifier of the subnetwork (address of the network concatenated with the uint96 identifier)
  • operator - address of the operator
  • amount - amount of the collateral to slash
  • captureTimestamp - time point when the stake was captured
  • hints - hints for checkpoints' indexes

VetoSlasher (Type 1)

The flow consists of three stages:

  1. Request Slashing
  2. Veto Slashing
  3. Execute Slashing (if not vetoed)

Let’s assume the veto duration period is set to 5 days and the epoch duration is set to 7 days.

Day 1 - Request Slashing

NetworkSlasher.sol
import {IVault} from "@symbioticfi/core/src/interfaces/vault/IVault.sol";
import {IVetoSlasher} from "@symbioticfi/core/src/interfaces/slasher/IVetoSlasher.sol";
import {Subnetwork} from "@symbioticfi/core/src/contracts/libraries/Subnetwork.sol";
 
address slasher = IVault(vault).slasher();
bytes32 subnetwork = Subnetwork.subnetwork(NETWORK, IDENTIFIER);
uint256 slashIndex = IVetoSlasher(slasher).requestSlash(
    subnetwork,
    operator,
    amount,
    captureTimestamp,
    hints
)

This call succeeds only if the following inequality holds:

requestSlashTimestamp + vetoDuration - captureTimestamp <= epochDuration

Days 1 to 5 - Veto Slashing

Resolver
IVetoSlasher(slasher).vetoSlash(slashIndex, hints)

Days 6 to 7 - Execute Slashing

If the slashing request wasn't vetoed:

NetworkSlasher.sol
IVetoSlasher(slasher).executeSlash(
    slashIndex,
    hints
)

Resolvers

If a vault uses a VetoSlasher, there is a veto phase (duration set during vault deployment) when the resolver can veto the request.

Networks can set the resolver via IVetoSlasher(slasher).setResolver(identifier, resolver, hints).

Next Steps

Relay On-Chain

Proceed to developing your protocol's on-chain components using Relay smart contracts.