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 ICollateral 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.

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:

Deposit, withdraw, slash, resolve lifecycle

vault-lifecycle

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

Each slashing incident consists of 3 separate actions:

  1. Request slash - requestSlash()
  2. Veto slash - vetoSlash() (optional)
  3. Execute slash - executeSlash()

The network's middleware calls the requestSlash() method with a given operator, resolver, and amount. In return, it receives the requestIndex of the slashing. The slashing is not applied instantly.

  • The slashing can be vetoed during the veto phase by the resolver, and such a slashing will not be executed.
  • If the veto phase is passed and the slashing is not vetoed, it can be executed via the executeSlash() method. Anyone can call this method after the veto phase has passed.
  • Important to note that each slashing has an executeDeadline. If the slashing was not executed before executeDeadline it can't be executed anymore.

Each slashing reduces the limits of the slashed operator and the network requested to slash. After the slashing all the user's funds are decreased proportionally.

Limits

All the limits described in this section are directly related to the slashing incidents and aim to create a more secure delegation process.

Operator-network limit

An operator-network limit is the maximum amount of funds the network can slash if it requests a slashing of the given operator. In other words, it means the maximum operator's stake in the network.

If such a slashing request is executed the operator-network limit will be decreased by the slashed amount. Deposits and withdrawals do not affect the limit. However, the OPERATOR_NETWORK_LIMIT_SET_ROLE holder can change it (decrease or increase) manually according to the totalSupply\text{totalSupply} of the vault and the current limits.

The operator-network limit is set for every operator-network pair, and the limits of different operator-network pairs do not affect each other. It can be accessed via the operatorNetworkLimit() method of the vault.

Network-resolver limit

A network-resolver limit is the maximum amount of funds the network can slash if it requests a slashing with the given resolver. In other words, it means the maximum stake delegated to the network using a certain resolver.

In general, its logic is the same as for the operator-network limit. However, the NETWORK_RESOLVER_LIMIT_SET_ROLE holder can change it, and it can be accessed via the networkResolverLimit() method.

Also, each network-resolver pair has its max network-resolver limit (which is set by the network) that defines the maximum value of the network-resolver limit that can be set. It serves as a cap of funds the network wishes to secure itself with. It can be accessed via the maxNetworkResolverLimit() function.

Details

A decrease in the limits produced by the appropriate role holder is not applied instantly but when the epoch + 1\text{epoch + 1} ends (considering that it is an epoch\text{epoch} at the moment). However, an increase in the limits is an instant action.

According to the mentioned limits the network can choose the operator set, allocate keys for validation, and define how much funds secure the network.

When the network N\text{N} attempts to slash the given operator Op\text{Op} with the given resolver R\text{R}, the maximum amount of funds it can slash is the following:

slashableAmount=min(totalSupply,min(networkResolverLimit(N,R),operatorNetworkLimit(Op,N)))\text{slashableAmount} = \min (\text{totalSupply}, \min (\text{networkResolverLimit}(\text{N}, \text{R}), \text{operatorNetworkLimit}(\text{Op}, \text{N})))

Rewards

Staker Rewards

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

  • activeSharesOfAt(account, timestamp) - active\text{active} shares of the user at a specific timestamp
  • activeSharesAt(timestamp) - 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 IRewardsDistributor interface to facilitate more generic reward distribution across networks.

  • IRewardsDistributor.version() - provides a version of the interface that a particular rewards distributor uses
  • IRewardsDistributor.distributeReward(network, token, amount, timestamp) - call to distribute amount of token on behalf of network using timestamp as a time point for calculations

The vault's rewards distributor's address can be obtained via the rewardsDistributor() method, which can be set by the REWARDS_DISTRIBUTOR_SET_ROLE holder.

DefaultRewardDistributor

As an example for the staker rewards, we provide the DefaultRewardDistributor contract, which includes two main functions:

  • distributeReward(network, token, amount, timestamp) - only whitelisted by the vault owner networks can call it
  • claimRewards(recipient, token, maxRewards, activeSharesOfHints)

This contract captures the state of shares at the given timestamp and distributes rewards according to this formula:

rewardstaker=activeSharesOfAt(staker,timestamp)activeSharesAt(timestamp)×distributedAmount\text{reward}_{\text{staker}} = \frac{\text{activeSharesOfAt}(\text{staker}, \text{timestamp})}{\text{activeSharesAt}(\text{timestamp})} \times \text{distributedAmount}

Operator Rewards

For operator rewards, the vault provides:

  • Vault.minStakeDuring(network, resolver, operator, duration) - Current active stake of an operator in the network, depending on the network epoch duration.

API reference

Vault Interface

interface IVault {
/**
* @notice Initial parameters needed for a vault deployment.
* @param collateral vault's underlying collateral
* @param epochDuration duration of the vault epoch (it determines sync points for withdrawals)
* @param vetoDuration duration of the veto period for a slash request
* @param executeDuration duration of the slash period for a slash request (after the veto duration has passed)
* @param rewardsDistributor address of the rewards distributor (it must implement IRewardsDistributor interface)
* @param adminFee admin fee (up to ADMIN_FEE_BASE inclusively)
* @param depositWhitelist if enabling deposit whitelist
*/
struct InitParams {
address collateral;
uint48 epochDuration;
uint48 vetoDuration;
uint48 executeDuration;
address rewardsDistributor;
uint256 adminFee;
bool depositWhitelist;
}

/**
* @notice Structure for a slashing limit.
* @param amount amount of the collateral that can be slashed
*/
struct Limit {
uint256 amount;
}

/**
* @notice Structure for a slashing limit that will be set in the future (if a new limit won't be set).
* @param amount amount of the collateral that can be slashed
* @param timestamp timestamp when the limit will be set
*/
struct DelayedLimit {
uint256 amount;
uint48 timestamp;
}

/**
* @notice Structure for a slash request.
* @param network network that requested the slash
* @param resolver resolver that can veto the slash
* @param operator operator that could be slashed (if the request is not vetoed)
* @param amount maximum amount of the collateral to be slashed
* @param vetoDeadline deadline for the resolver to veto the slash (exclusively)
* @param executeDeadline deadline to execute slash (exclusively)
* @param completed if the slash was vetoed/executed
*/
struct SlashRequest {
address network;
address resolver;
address operator;
uint256 amount;
uint48 vetoDeadline;
uint48 executeDeadline;
bool completed;
}

/**
* @notice Emitted when a deposit is made.
* @param depositor account that made the deposit
* @param onBehalfOf account the deposit was made on behalf of
* @param amount amount of the collateral deposited
* @param shares amount of the active shares minted
*/
event Deposit(address indexed depositor, address indexed onBehalfOf, uint256 amount, uint256 shares);

/**
* @notice Emitted when a withdrawal is made.
* @param withdrawer account that made the withdrawal
* @param claimer account that needs to claim the withdrawal
* @param amount amount of the collateral withdrawn
* @param burnedShares amount of the active shares burned
* @param mintedShares amount of the epoch withdrawal shares minted
*/
event Withdraw(
address indexed withdrawer, address indexed claimer, uint256 amount, uint256 burnedShares, uint256 mintedShares
);

/**
* @notice Emitted when a claim is made.
* @param claimer account that claimed
* @param recipient account that received the collateral
* @param amount amount of the collateral claimed
*/
event Claim(address indexed claimer, address indexed recipient, uint256 amount);

/**
* @notice Emitted when a slash request is created.
* @param slashIndex index of the slash request
* @param network network that requested the slash
* @param resolver resolver that can veto the slash
* @param operator operator that could be slashed (if the request is not vetoed)
* @param slashAmount maximum amount of the collateral to be slashed
* @param vetoDeadline deadline for the resolver to veto the slash (exclusively)
* @param executeDeadline deadline to execute slash (exclusively)
*/
event RequestSlash(
uint256 indexed slashIndex,
address indexed network,
address resolver,
address indexed operator,
uint256 slashAmount,
uint48 vetoDeadline,
uint48 executeDeadline
);

/**
* @notice Emitted when a slash request is executed.
* @param slashIndex index of the slash request
* @param slashedAmount amount of the collateral slashed
*/
event ExecuteSlash(uint256 indexed slashIndex, uint256 slashedAmount);

/**
* @notice Emitted when a slash request is vetoed.
* @param slashIndex index of the slash request
*/
event VetoSlash(uint256 indexed slashIndex);

/**
* @notice Emitted when a maximum network-resolver limit is set.
* @param network address of the network
* @param resolver address of the resolver
* @param amount maximum network-resolver limit that can be set
*/
event SetMaxNetworkResolverLimit(address indexed network, address indexed resolver, uint256 amount);

/**
* @notice Emitted when a network-resolver limit is set.
* @param network address of the network
* @param resolver address of the resolver
* @param amount maximum amount of the collateral that can be slashed
*/
event SetNetworkResolverLimit(address indexed network, address indexed resolver, uint256 amount);

/**
* @notice Emitted when an operator-network limit is set.
* @param operator address of the operator
* @param network address of the network
* @param amount maximum amount of the collateral that can be slashed
*/
event SetOperatorNetworkLimit(address indexed operator, address indexed network, uint256 amount);

/**
* @notice Emitted when a rewards distributor is set.
* @param rewardsDistributor address of the rewards distributor
*/
event SetRewardsDistributor(address rewardsDistributor);

/**
* @notice Emitted when an admin fee is set.
* @param adminFee admin fee
*/
event SetAdminFee(uint256 adminFee);

/**
* @notice Emitted when a deposit whitelist status is enabled/disabled.
* @param depositWhitelist if enabled deposit whitelist
*/
event SetDepositWhitelist(bool depositWhitelist);

/**
* @notice Emitted when a depositor whitelist status is set.
* @param account account for which the whitelist status is set
* @param status if whitelisted the account
*/
event SetDepositorWhitelistStatus(address indexed account, bool status);

/**
* @notice Get the maximum admin fee (= 100%).
* @return maximum admin fee
*/
function ADMIN_FEE_BASE() external view returns (uint256);

/**
* @notice Get the rewards distributor setter's role.
*/
function REWARDS_DISTRIBUTOR_SET_ROLE() external view returns (bytes32);

/**
* @notice Get the admin fee setter's role.
*/
function ADMIN_FEE_SET_ROLE() external view returns (bytes32);

/**
* @notice Get the deposit whitelist enabler/disabler's role.
*/
function DEPOSIT_WHITELIST_SET_ROLE() external view returns (bytes32);

/**
* @notice Get the depositor whitelist status setter's role.
*/
function DEPOSITOR_WHITELIST_ROLE() external view returns (bytes32);

/**
* @notice Get the network-resolver limit setter's role.
*/
function NETWORK_RESOLVER_LIMIT_SET_ROLE() external view returns (bytes32);

/**
* @notice Get the operator-network limit setter's role.
*/
function OPERATOR_NETWORK_LIMIT_SET_ROLE() external view returns (bytes32);

/**
* @notice Get the network registry's address.
* @return address of the network registry
*/
function NETWORK_REGISTRY() external view returns (address);

/**
* @notice Get the network middleware service's address.
* @return address of the network middleware service
*/
function NETWORK_MIDDLEWARE_SERVICE() external view returns (address);

/**
* @notice Get the network-vault opt-in service's address.
* @return address of the network-vault opt-in service
*/
function NETWORK_VAULT_OPT_IN_SERVICE() external view returns (address);

/**
* @notice Get the operator-vault opt-in service's address.
* @return address of the operator-vault opt-in service
*/
function OPERATOR_VAULT_OPT_IN_SERVICE() external view returns (address);

/**
* @notice Get the operator-network opt-in service's address.
* @return address of the operator-network opt-in service
*/
function OPERATOR_NETWORK_OPT_IN_SERVICE() external view returns (address);

/**
* @notice Get a vault collateral.
* @return vault's underlying collateral
*/
function collateral() external view returns (address);

/**
* @notice Get a time point of the epoch duration set.
* @return time point of the epoch duration set
*/
function epochDurationInit() external view returns (uint48);

/**
* @notice Get a duration of the vault epoch.
* @return duration of the epoch
*/
function epochDuration() external view returns (uint48);

/**
* @notice Get an epoch at a given timestamp.
* @param timestamp time point to get the epoch at
* @return epoch at the timestamp
* @dev Reverts if the timestamp is less than the start of the epoch 0.
*/
function epochAt(uint48 timestamp) external view returns (uint256);

/**
* @notice Get a current vault epoch.
* @return current epoch
*/
function currentEpoch() external view returns (uint256);

/**
* @notice Get a start of the current vault epoch.
* @return start of the current epoch
*/
function currentEpochStart() external view returns (uint48);

/**
* @notice Get a start of the previous vault epoch.
* @return start of the previous epoch
* @dev Reverts if the current epoch is 0.
*/
function previousEpochStart() external view returns (uint48);

/**
* @notice Get a duration during which resolvers can veto slash requests.
* @return duration of the veto period
*/
function vetoDuration() external view returns (uint48);

/**
* @notice Get a duration during which slash requests can be executed (after the veto period).
* @return duration of the slash period
*/
function executeDuration() external view returns (uint48);

/**
* @notice Get a rewards distributor.
* @return address of the rewards distributor
* @dev It must implement the IRewardsDistributor interface.
*/
function rewardsDistributor() external view returns (address);

/**
* @notice Get an admin fee.
* @return admin fee
*/
function adminFee() external view returns (uint256);

/**
* @notice Get if the deposit whitelist is enabled.
* @return if the deposit whitelist is enabled
*/
function depositWhitelist() external view returns (bool);

/**
* @notice Get if a given account is whitelisted as a depositor.
* @param account address to check
* @return if the account is whitelisted as a depositor
*/
function isDepositorWhitelisted(address account) external view returns (bool);

/**
* @notice Get a timestamp when the first deposit was made by a particular account.
* @param account account to get the timestamp when the first deposit was made for
* @return timestamp when the first deposit was made
*/
function firstDepositAt(address account) external view returns (uint48);

/**
* @notice Get a total amount of the collateral that can be slashed
* in `duration` seconds (if there will be no new deposits and slash executions).
* @param duration duration to get the total amount of the slashable collateral in
* @return total amount of the slashable collateral in `duration` seconds
*/
function totalSupplyIn(uint48 duration) external view returns (uint256);

/**
* @notice Get a total amount of the collateral that can be slashed.
* @return total amount of the slashable collateral
*/
function totalSupply() external view returns (uint256);

/**
* @notice Get a total amount of active shares in the vault at a given timestamp.
* @param timestamp time point to get the total amount of active shares at
* @return total amount of active shares at the timestamp
*/
function activeSharesAt(uint48 timestamp) external view returns (uint256);

/**
* @notice Get a total amount of active shares in the vault.
* @return total amount of active shares
*/
function activeShares() external view returns (uint256);

/**
* @notice Get a total amount of active supply in the vault at a given timestamp.
* @param timestamp time point to get the total active supply at
* @return total amount of active supply at the timestamp
*/
function activeSupplyAt(uint48 timestamp) external view returns (uint256);

/**
* @notice Get a total amount of active supply in the vault.
* @return total amount of active supply
*/
function activeSupply() external view returns (uint256);

/**
* @notice Get a total amount of active shares for a particular account at a given timestamp using a hint.
* @param account account to get the amount of active shares for
* @param timestamp time point to get the amount of active shares for the account at
* @param hint hint for the checkpoint index
* @return amount of active shares for the account at the timestamp
*/
function activeSharesOfAtHint(address account, uint48 timestamp, uint32 hint) external view returns (uint256);

/**
* @notice Get a total amount of active shares for a particular account at a given timestamp.
* @param account account to get the amount of active shares for
* @param timestamp time point to get the amount of active shares for the account at
* @return amount of active shares for the account at the timestamp
*/
function activeSharesOfAt(address account, uint48 timestamp) external view returns (uint256);

/**
* @notice Get an amount of active shares for a particular account.
* @param account account to get the amount of active shares for
* @return amount of active shares for the account
*/
function activeSharesOf(address account) external view returns (uint256);

/**
* @notice Get a total number of the activeSharesOf checkpoints for a particular account.
* @param account account to get the total number of the activeSharesOf checkpoints for
* @return total number of the activeSharesOf checkpoints for the account
*/
function activeSharesOfCheckpointsLength(address account) external view returns (uint256);

/**
* @notice Get an activeSharesOf checkpoint for a particular account at a given index.
* @param account account to get the activeSharesOf checkpoint for
* @param pos index of the checkpoint
* @return timestamp time point of the checkpoint
* @return amount of active shares at the checkpoint
*/
function activeSharesOfCheckpoint(address account, uint32 pos) external view returns (uint48, uint256);

/**
* @notice Get an active balance for a particular account at a given timestamp.
* @param account account to get the active balance for
* @param timestamp time point to get the active balance for the account at
* @return active balance for the account at the timestamp
*/
function activeBalanceOfAt(address account, uint48 timestamp) external view returns (uint256);

/**
* @notice Get an active balance for a particular account.
* @param account account to get the active balance for
* @return active balance for the account
*/
function activeBalanceOf(address account) external view returns (uint256);

/**
* @notice Get a total amount of the withdrawals at a given epoch.
* @param epoch epoch to get the total amount of the withdrawals at
* @return total amount of the withdrawals at the epoch
*/
function withdrawals(uint256 epoch) external view returns (uint256);

/**
* @notice Get a total amount of withdrawal shares at a given epoch.
* @param epoch epoch to get the total amount of withdrawal shares at
* @return total amount of withdrawal shares at the epoch
*/
function withdrawalShares(uint256 epoch) external view returns (uint256);

/**
* @notice Get an amount of pending withdrawal shares for a particular account at a given epoch (zero if claimed).
* @param epoch epoch to get the amount of pending withdrawal shares for the account at
* @param account account to get the amount of pending withdrawal shares for
* @return amount of pending withdrawal shares for the account at the epoch
*/
function pendingWithdrawalSharesOf(uint256 epoch, address account) external view returns (uint256);

/**
* @notice Get pending withdrawals for a particular account at a given epoch (zero if claimed).
* @param epoch epoch to get the pending withdrawals for the account at
* @param account account to get the pending withdrawals for
* @return pending withdrawals for the account at the epoch
*/
function pendingWithdrawalsOf(uint256 epoch, address account) external view returns (uint256);

/**
* @notice Get a maximum amount of collateral that can be slashed
* for a particular network, resolver, and operator in `duration` seconds.
* @param network address of the network
* @param resolver address of the resolver
* @param operator address of the operator
* @param duration duration to get the slashable amount in
* @return maximum amount of the collateral that can be slashed in `duration` seconds
*/
function slashableAmountIn(
address network,
address resolver,
address operator,
uint48 duration
) external view returns (uint256);

/**
* @notice Get a maximum amount of collateral that can be slashed for a particular network, resolver, and operator.
* @param network address of the network
* @param resolver address of the resolver
* @param operator address of the operator
* @return maximum amount of the collateral that can be slashed
*/
function slashableAmount(address network, address resolver, address operator) external view returns (uint256);

/**
* @notice Get a total number of slash requests.
* @return total number of slash requests
*/
function slashRequestsLength() external view returns (uint256);

/**
* @notice Get a particular slash request.
* @param slashIndex index of the slash request
* @return network network that requested the slash
* @return resolver resolver that can veto the slash
* @return operator operator that could be slashed (if the request is not vetoed)
* @return amount maximum amount of the collateral to be slashed
* @return vetoDeadline deadline for the resolver to veto the slash (exclusively)
* @return executeDeadline deadline to execute slash (exclusively)
* @return completed if the slash was vetoed/executed
*/
function slashRequests(uint256 slashIndex)
external
view
returns (
address network,
address resolver,
address operator,
uint256 amount,
uint48 vetoDeadline,
uint48 executeDeadline,
bool completed
);

/**
* @notice Get a maximum network-resolver limit for a particular network and resolver.
* @param network address of the network
* @param resolver address of the resolver
* @return maximum network-resolver limit
*/
function maxNetworkResolverLimit(address network, address resolver) external view returns (uint256);

/**
* @notice Get a network-resolver limit for a particular network and resolver in `duration` seconds.
* @param network address of the network
* @param resolver address of the resolver
* @param duration duration to get the network-resolver limit in
* @return network-resolver limit in `duration` seconds
*/
function networkResolverLimitIn(
address network,
address resolver,
uint48 duration
) external view returns (uint256);

/**
* @notice Get a network-resolver limit for a particular network and resolver.
* @param network address of the network
* @param resolver address of the resolver
* @return network-resolver limit
*/
function networkResolverLimit(address network, address resolver) external view returns (uint256);

/**
* @notice Get the next network-resolver limit for a particular network and resolver.
* @param network address of the network
* @param resolver address of the resolver
* @return next network-resolver limit
* @return timestamp when the limit will be set
*/
function nextNetworkResolverLimit(address network, address resolver) external view returns (uint256, uint48);

/**
* @notice Get an operator-network limit for a particular operator and network in `duration` seconds.
* @param operator address of the operator
* @param network address of the network
* @param duration duration to get the operator-network limit in
* @return operator-network limit in `duration` seconds
*/
function operatorNetworkLimitIn(
address operator,
address network,
uint48 duration
) external view returns (uint256);

/**
* @notice Get an operator-network limit for a particular operator and network.
* @param operator address of the operator
* @param network address of the network
* @return operator-network limit
*/
function operatorNetworkLimit(address operator, address network) external view returns (uint256);

/**
* @notice Get the next operator-network limit for a particular operator and network.
* @param operator address of the operator
* @param network address of the network
* @return next operator-network limit
* @return timestamp when the limit will be set
*/
function nextOperatorNetworkLimit(address operator, address network) external view returns (uint256, uint48);

/**
* @notice Get a minimum stake that a given network will be able to slash using a particular resolver
* for a certain operator during `duration` (if no cross-slashing).
* @param network address of the network
* @param resolver address of the resolver
* @param operator address of the operator
* @param duration duration to get the minimum slashable stake during
* @return minimum slashable stake during `duration`
*/
function minStakeDuring(
address network,
address resolver,
address operator,
uint48 duration
) external view returns (uint256);

/**
* @notice Deposit collateral into the vault.
* @param onBehalfOf account the deposit is made on behalf of
* @param amount amount of the collateral to deposit
* @return shares amount of the active shares minted
*/
function deposit(address onBehalfOf, uint256 amount) external returns (uint256 shares);

/**
* @notice Withdraw collateral from the vault (it will be claimable after the next epoch).
* @param claimer account that needs to claim the withdrawal
* @param amount amount of the collateral to withdraw
* @return burnedShares amount of the active shares burned
* @return mintedShares amount of the epoch withdrawal shares minted
*/
function withdraw(address claimer, uint256 amount) external returns (uint256 burnedShares, uint256 mintedShares);

/**
* @notice Claim collateral from the vault.
* @param recipient account that receives the collateral
* @param epoch epoch to claim the collateral for
* @return amount amount of the collateral claimed
*/
function claim(address recipient, uint256 epoch) external returns (uint256 amount);

/**
* @notice Request a slash using a network and a resolver for a particular operator by a given amount.
* @param network address of the network
* @param resolver address of the resolver
* @param operator address of the operator
* @param amount maximum amount of the collateral to be slashed
* @return slashIndex index of the slash request
* @dev Only network middleware can call this function.
*/
function requestSlash(
address network,
address resolver,
address operator,
uint256 amount
) external returns (uint256 slashIndex);

/**
* @notice Execute a slash with a given slash index.
* @param slashIndex index of the slash request
* @return slashedAmount amount of the collateral slashed
* @dev Anyone can call this function.
*/
function executeSlash(uint256 slashIndex) external returns (uint256 slashedAmount);

/**
* @notice Veto a slash with a given slash index.
* @param slashIndex index of the slash request
* @dev Only a resolver can call this function.
*/
function vetoSlash(uint256 slashIndex) external;

/**
* @notice Set a maximum network-resolver limit.
* @param resolver address of the resolver
* @param amount maximum network-resolver limit that can be set
* @dev Only a network can call this function.
*/
function setMaxNetworkResolverLimit(address resolver, uint256 amount) external;

/**
* @notice Set a network-resolver limit for a particular network and resolver.
* @param network address of the network
* @param resolver address of the resolver
* @param amount new maximum amount of the collateral that can be slashed
* @dev Only the NETWORK_RESOLVER_LIMIT_SET_ROLE holder can call this function.
*/
function setNetworkResolverLimit(address network, address resolver, uint256 amount) external;

/**
* @notice Set an operator-network limit for a particular operator and network.
* @param operator address of the operator
* @param network address of the network
* @param amount new maximum amount of the collateral that can be slashed
* @dev Only the OPERATOR_NETWORK_LIMIT_SET_ROLE holder can call this function.
*/
function setOperatorNetworkLimit(address operator, address network, uint256 amount) external;

/**
* @notice Set a rewards distributor.
* @param rewardsDistributor address of the rewards distributor
* @dev Only the REWARDS_DISTRIBUTOR_SET_ROLE holder can call this function.
*/
function setRewardsDistributor(address rewardsDistributor) external;

/**
* @notice Set an admin fee.
* @param adminFee admin fee (up to ADMIN_FEE_BASE inclusively)
* @dev Only the ADMIN_FEE_SET_ROLE holder can call this function.
*/
function setAdminFee(uint256 adminFee) external;

/**
* @notice Enable/disable deposit whitelist.
* @param status if enabling deposit whitelist
* @dev Only the DEPOSIT_WHITELIST_SET_ROLE holder can call this function.
*/
function setDepositWhitelist(bool status) external;

/**
* @notice Set a depositor whitelist status.
* @param account account for which the whitelist status is set
* @param status if whitelisting the account
* @dev Only the DEPOSITOR_WHITELIST_ROLE holder can call this function.
*/
function setDepositorWhitelistStatus(address account, bool status) external;
}

RewardsDistributor Interface

interface IRewardsDistributor {
/**
* @notice Emitted when a reward is distributed.
* @param network network on behalf of which the reward is distributed
* @param token address of the token
* @param amount amount of tokens
* @param timestamp time point stakes must be taken into account at
*/
event DistributeReward(address indexed network, address indexed token, uint256 amount, uint48 timestamp);

/**
* @notice Get a version of the rewards distributor (different versions mean different interfaces).
* @return version of the rewards distributor
* @dev Must return 1 for this one.
*/
function version() external view returns (uint64);

/**
* @notice Distribute rewards on behalf of a particular network using a given token.
* @param network network on behalf of which the reward to distribute
* @param token address of the token
* @param amount amount of tokens
* @param timestamp time point stakes must be taken into account at
*/
function distributeReward(address network, address token, uint256 amount, uint48 timestamp) external;
}