Skip to main content

Vaults

Description

Vaults are the delegation and restaking management layer of Symbiotic. They handle three crucial parts of the Symbiotic economy:

  • Accounting: Vaults handle deposits, withdrawals, and slashings of collaterals and in turn their underlying assets.
  • Delegation Strategies: Vault deployers/owners define delegation and restaking strategies to operators across Symbiotic networks, which networks have to opt into.
  • Reward Distribution: Vaults distribute staking rewards from networks to collateral depositors.

Vaults are configurable and can be deployed in an immutable, pre-configured way, or specifying an owner that is able to update vault parameters. Vaults are expected to be used by operators and curators such as crypto institutions or liquid (re)staking protocols to create differentiated products, e.g.:

  • Operator-Specific Vaults: Operators may create vaults with collateral restaked to their infrastructure across any configuration of networks. An operator can create multiple vaults with differing configurations to service their clients without requiring additional node infrastructure.
  • Curated Multi-Operator Vaults: curated configurations of restaked networks and delegation strategies to a diversified set of operators. Curated vaults can additionally set custom slashing limits to cap the collateral amount that can be slashed for specific operators or networks. The terms of these commitments need to be accepted by networks that vaults seek to provide their curation for.
  • Immutable Pre-Configured Vaults: Vaults can be deployed with pre-configured rules that cannot be updated to provide extra protection for users that are not comfortable with risks associated with their vault curator being able to add additional restaked networks or change configurations in any other way.

vaults

Technical overview

Each vault has a predefined collateral token. The address of this token can be obtained via the collateral() method of the vault. The collateral token must satisfy the IERC20 interface (see Collateral details). All the operations and accounting within the vault are performed only with the collateral token. However, the rewards within the vault can be in different tokens. All the funds are represented in shares internally but the external interaction is done in absolute amounts of funds.

The Vault contract consists of three modules:

  1. Accounting
  2. Slashing logic
  3. Limits and delegation logic

Vault modules

Accounting is performed within the vault itself. Slashing logic is handled by the Slasher module. One important aspect not yet mentioned is the validation of slashing requirements.

When a slashing request is sent, the system verifies its validity. Specifically, it checks that the operator is opted into the vault, and is interacting with the network.

We use separate OptIn service contracts to connect vaults, operators, and networks.

  1. The operator must be opted into the vault.
  2. The operator must be opted into the network.

These connections are made using OptIn service contracts.

If all opt-ins are confirmed, the operator is considered to be working with the network through the vault as a stake provider. Only then can the operator be slashed.

To get guarantees, the network calls the Delegator module. In case of slashing, it calls the Slasher module, which will then call the Vault and the Delegator module. This module also checks the provided guarantees as well as the slashed amount of funds to ensure it does not exceed the guaranteed amount.

Accounting

Symbiotic allows for a majority of mechanics to be flexible, however, it provides strict guarantees regarding vault slashing to the networks and stakers as defined in this diagram:

A network can use flexible mechanics to keep its operator set state up-to-date, e.g., it’s convenient to use a conveyor approach for updating the stakes while keeping slashing guarantees for every particular version of the operator set:

  1. At the beginning of every epoch the network can capture the state from vaults and their stake amount (this doesn’t require any on-chain interactions).
  2. After this, the network will have slashing guarantees until the end of the next epoch, so it can use this state at least for one epoch.
  3. When the epoch finishes and a slashing incident has taken place, the network will have time not less than a single epoch to request-veto-execute slash and go back to step 1 in parallel.

Conveyor approach

vault-conveyor

Epochs

The size of the epoch is not specified. However, all the epochs are consecutive and have an equal constant, defined at the moment of deployment size. Next in the text, we refer to it as EPOCH\text{EPOCH}.

Definitions

  • active\text{active} balance - a pure balance of the vault/user that is not in the withdrawal process
  • epoch\text{epoch} - a current epoch
  • Wepoch\text{W}_\text{epoch} - withdrawals that will be claimable in the epoch + 1\text{epoch + 1}

Constraints

  • totalSupply=active+Wepoch+Wepoch + 1\text{totalSupply} = \text{active} + \text{W}_\text{epoch} + \text{W}_\text{epoch + 1} - a total amount of the collateral that can be slashed at the moment

  • During withdrawal:

  1. activeactiveamount\text{active} \rightarrow \text{active} - \text{amount}   2. Wepoch + 1Wepoch + 1+amount\text{W}_\text{epoch + 1} \rightarrow \text{W}_\text{epoch + 1} + \text{amount}

  • During deposit:

  1. activeactive+amount\text{active} \rightarrow \text{active} + \text{amount}

  • During slashing:

  1. q=1amounttotalSupply\text{q} = \text{1} - \frac{\text{amount}}{\text{totalSupply}}   2. activeactiveq\text{active} \rightarrow \text{active} \cdot \text{q}   3. WepochWepochq\text{W}_\text{epoch} \rightarrow \text{W}_\text{epoch} \cdot \text{q}   4. Wepoch + 1Wepoch + 1q\text{W}_\text{epoch + 1} \rightarrow \text{W}_\text{epoch + 1} \cdot \text{q}

  • k>0,Wepoch - k\forall \text{k} > \text{0}, \text{W}_\text{epoch - k} - claimable

  • k0,Wepoch + k\forall \text{k} \ge \text{0}, \text{W}_\text{epoch + k} - slashable and not claimable

Deposits

Any holder of the collateral token can deposit it into the vault using the deposit() method of the vault. In turn, the user receives shares. Any deposit instantly increases the active\text{active} balance of the vault.

Withdrawals

Any depositor can withdraw his funds using the withdraw() method of the vault. The withdrawal process consists of two parts: a request and a claim.

Consider the user requests the withdrawal at epoch\text{epoch}. The user can claim the withdrawal when the epoch + 1\text{epoch + 1} ends. Hence, a withdrawal delay varies from EPOCH + 1\text{EPOCH + 1} to 2EPOCH\text{2} \cdot \text{EPOCH}. Such funds are immediately reduced from the active\text{active} balance of the vault, however, the funds still can be slashed. Important to note that when the epoch + 1\text{epoch + 1} ends the funds can't be slashed anymore and can be claimed.

Slashing

In the Symbiotic protocol, a slasher module is optional. However, the text below describes the core principles when the vault has a slasher module.

general slashing

Consider the network captures the stake of the operator at moment tt. To do so, it calls the stakeAtstakeAt function with a given network, operator, and timestamptimestamp (moment of capturing guarantees, which should be in the past, when the blocks are already finalized). Let SS be the resulting stake. This value is valid for dd = EPOCH_SIZE time. From this point, the pair (S,t)(S, t) is a guarantee given by the vault to the network. The guarantee is valid from the timestamptimestamp moment to timestamp+dtimestamp + d.

guarantee of slashing

Slashing in Symbiotic is implemented through separate modules connected to the vault.

Essentially, slashing is the enforcement of the guarantees described above. Currently, there are two types of slashing: instant and veto-slashing.

Instant slashing

Instant slashing is executed immediately when a request comes in.

instant slashing

Veto slashing

Veto slashing consists of two stages: the Veto Phase and the Execute Phase.

veto slashing

After submitting a slashing request, there is a period of VV time to issue a veto on the slashing. The veto can be made by designated participants in the vault, known as resolvers. Each network can either have a resolver or not, and a resolver can cancel all of the slashing or pass the slashing to the next phase. If the slashing is not resolved after this phase, there is a period of E=EPOCHV(request_timestampcapture_timestamp)E = EPOCH - V - (request\_timestamp - capture\_timestamp) time to execute the slashing. Only a network middleware can execute it. The network must consider how much time is left until the end of the guarantee before sending the slashing request.

Limits

Delegator is a separate module that connects to the Vault. The purpose of this module is to set limits for operators and networks, with the limits representing the operators' stake and the networks' stake. Currently, there are two types of delegators implemented:

  1. FullRestakeDelegator
  2. NetworkRestakeDelegator

Symbiotic is a restaking protocol, and these modules differ in how the restaking process is carried out. The modules will be described further:

There are obvious re-staking trade-offs with cross-slashing when stake can be reduced asynchronously. Networks should manage these risks by:

  1. Maintaining a safe re-staking ratio.
  2. Choosing the right stake-capturing ratio to minimize reaction time.

Here we describe common technical information for both modules.

Let NLjNL_{j} be the limit of the jthj^{th} network. This limit can be considered as the network's stake, meaning the amount of funds delegated to the network. NLjNL_{j} is set by a special role in the delegator module. However, the module normalizes it. Let the vault’s active supply be ASAS.

Then NSj=min(NLj,AS)NS_{j} = \min(NL_{j}, AS) - network stake.

Additionally, the modules have a max network limit mNLjmNL_{j}, which is set by the networks themselves. This serves as the maximum possible amount of funds that can be delegated to the network. It is guaranteed that NLjmNLjNL_{j} \leq mNL_{j}. This limit is mainly used by networks to manage a safe restaking ratio.

If the ithi^{th} operator is slashed by xx in the jthj^{th} network his stake can be decreased:

NLj(new)=NLjxNL_{j}(new) = NL_{j} - x

Also, it should be mentioned that in the case of slashing, these modules have special hooks that call the method to process the change of limits. In general, we don't need such a method to exist because all the limits can be changed manually and instantly w/o changing already given guarantees.

NetworkRestakeDelegator

NetworkRestakeDelegator

The main goal of this delegator is to allow restaking between multiple networks but restrict operators from being restaked within the same network. The operators' stakes are represented as shares in the network's stake.

Each network's stakes are divided across operators.

NetworkRestakeDelegator miltiple networks

Let the ithi^{th} operator’s share in the jthj^{th} network be λi,j\lambda_{i, j}.

Then

  1. λi,jNSj\lambda_{i, j} \cdot NS_{j} - the ithi^{th} operator’s stake in the jthj^{th} network
  2. iλi,jNSj=NSj\sum_{i}\lambda_{i, j} \cdot NS_{j} = NS_{j}

We can conclude that slashing decreases the share of a specific operator and does not affect other operators in the same network. However, the TSTS of the vault will decrease after slashing, which can cause other NSjNS_{j'} for jjj' \neq j to decrease.

FullRestakeDelegator

FullRestakeDelegator

This module performs restaking for both operators and networks simultaneously. The stake in the vault is shared between operators and networks. The designated role can change these stakes. If a network slashes an operator, it may cause a decrease in the stake of other restaked operators even in the same network. However, it depends on the distribution of the stakes in the module.

In this module, we introduce so-called limits for operators. Each operator has its own limit in every network.

Let the ithi^{th} operator’s limit in the jthj^{th} network be OpLi,jOpL_{i, j}. Such a limit is considered a stake of the operators.

OpSi,j=min(OpLi,j,NSj)OpS_{i, j} = min(OpL_{i, j}, NS_j) - the ithi^{th} operator’s stake in the jthj^{th} network

As already stated, this module enables restaking for operators. This means the sum of operators' stakes in the network can exceed the network’s own stake. This module is useful when operators have an insurance fund for slashing and are curated by a trusted party.

Such a slashing can lead to a situation where all the other operators' stakes will decrease.

Rewards

Staker Rewards

For staker rewards calculation, the vault provides the following data:

  • activeSharesOfAt(account, timestamp, hint) - active\text{active} shares of the user at a specific timestamp
  • activeSharesAt(timestamp, hint) - total active\text{active} shares at a specific timestamp.
  • Other checkpointed getters

Reward processing is not integrated into the vault's functionality. Instead, external reward contracts should manage this using the provided data.

However, we created the first version of the IStakerRewards interface to facilitate more generic reward distribution across networks.

  • IStakerRewards.version() - provides a version of the interface that a particular staker rewards contract uses.
  • IStakerRewards.distributeReward(network, token, amount, data) - call to distribute amount of token on behalf of network.

Operator Rewards

For operator rewards, the delegator module of the vault provides:

  • Delegator.stakeAt(network, operator, timestamp, hint) - Active stake of an operator in the network.