Skip to content

Slashing

Read Learn first

Slashing is a penalty mechanism enforced by a network to deter operators from breaking their commitments. Such violations may include failing to complete tasks properly or accurately. Slashing typically results in the burning or redistribution of the operator’s staked funds.

Slasher Module

Each Symbiotic Vault has an immutably set Slasher module implementation. In general, 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 an amount of collateral still slashable for the given captureTimestamp at the current moment.

Slashing Guarantees

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

Hence, the following inequality must hold:

executeSlashTimestamp - captureTimestamp <= epochDuration

Slasher (Type 0)

Slasher performs an instant execution of the slashing request 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 the Vault has a VetoSlasher type, there is a veto phase, whose duration is set during the vault's deployment, when the resolver can veto the request.

The resolver can be set by Network via IVetoSlasher(slasher).setResolver(identifier, resolver, hints).

Next Steps

Relay On-Chain

Proceed to the the development of your protocol's on-chain part using Relay smart contracts.