Skip to content
LogoLogo

Events

This page provides a complete overview of event handling and math across the Symbiotic system.

Vault Stake

Consider the following events monitoring only a single vault.

Deposit

  • event Deposit(address indexed depositor, address indexed onBehalfOf, uint256 amount, uint256 shares)
    • depositor - irrelevant in the current context
    • onBehalfOf - an address of the user that receives the deposited funds
    • amount - a number of collateral tokens deposited
    • shares - a number of shares onBehalfOf user received

Bucket accounting (why amount and shares coexist)

  1. Alice deposits 12 → userShares(alice)=12, totalAssets=12, totalShares=12 → balance = 12.
  2. Bob deposits 8 → userShares(bob)=8, totalAssets=20, totalShares=20 → balance = 8.
  3. Slash 10 → totalAssets=10 → balances: Alice 6, Bob 4.
  4. Jack deposits 10 → minted shares = depositAmount * totalShares / totalAssets = 10 * 20 / 10 = 20userShares(jack)=20, totalAssets=20, totalShares=40 → balances: Alice 6, Bob 4, Jack 10.

Off-chain updates per Deposit

  • activeStakeBucket.userShares(onBehalfOf) += shares
  • activeStakeBucket.totalAssets += amount
  • activeStakeBucket.totalShares += shares

Withdraw

  • event Withdraw(address indexed withdrawer, address indexed claimer, uint256 amount, uint256 burnedShares, uint256 mintedShares)
    • withdrawer - an address that loses the withdrawn funds
    • claimer - an address that receives withdrawn funds to be claimed
    • amount - a number of collateral tokens withdrawn
    • burnedShares - a number of shares withdrawer lost at the activeStakeBucket
    • mintedShares - a number of shares claimer received

Symbiotic Vault works using the epochs mechanic. What does it mean in the context of withdrawals:

Let’s assume the epoch duration of the Vault is 7 days, and the 0th epoch started at timestamp = 0. Right now, it is a timestamp = 0.

  1. Alice deposited 10 (activeStakeBucket's state has changed following the logic mentioned above)

Timestamp = 3 days (the 0th epoch)

  1. Alice withdraws 3, which means:
    • Decrease activeStakeBucket.userShares(alice) by 3 (withdrawal logic from the bucket is similar to a deposit).
    • Decrease activeStakeBucket.totalAssets by 3 (withdrawal logic from the bucket is similar to a deposit).
    • Decrease activeStakeBucket.totalShares by 3 (withdrawal logic from the bucket is similar to a deposit).
    • Deposit 3 into withdrawalsBucket_1 (1 means it is a bucket related to the 1st epoch; “the 1st epoch” because it is the next one)

Timestamp = 10 days (the 1st epoch)

  1. Alice withdraws 4, which means:
    • Withdraw 4 from activeStakeBucket
    • Deposit 4 to withdrawalsBucket_2

Off-chain updates per Withdraw

  • activeStakeBucket.userShares(withdrawer) -= burnedShares
  • activeStakeBucket.totalAssets -= amount
  • activeStakeBucket.totalShares -= burnedShares
  • withdrawalsBucket_i.userShares(claimer) += mintedShares
  • withdrawalsBucket_i.totalAssets += amount
  • withdrawalsBucket_i.totalShares += mintedShares

Slash

  • event OnSlash(uint256 amount, uint48 captureTimestamp, uint256 slashedAmount)
    • amount - a number of collateral tokens that were requested to be slashed
    • captureTimestamp - a capture timestamp the slash was requested for
    • slashedAmount - a number of collateral tokens that were actually slashed

Basically, the logic behind the slashing is the following:

  • A network receives the stake amount only depending on the active stake at the given time point.
  • Also, we know that the withdrawals from the current epoch are marked as withdrawalsBucket_i, where iis the next epoch.
  • Therefore, omitting some details, the slashing can be divided into 2 cases:
    1. If eventTimestamp and captureTimestamp are in different epochs (it can be simply checked via Vault.epochAt(timestamp) function).
      • Let’s say eventEpoch = Vault.epochAt(eventTimestamp)
      • Then the whole slashable amount for this slashing slashableAmount = activeStakeBucket.totalAssets + withdrawalsBucket_{eventEpoch}.totalAssets + withdrawalsBucket_{eventEpoch + 1}.totalAssets
      • The slashedAmount is proportionally decreased from each bucket, e.g., activeStakeSlashed = slashedAmount * activeStakeBucket.totalAssets / slashableAmount
    2. If eventTimestamp and captureTimestamp are in the same epoch (it can be simply checked via Vault.epochAt(timestamp) function).
      • Let’s say eventEpoch = Vault.epochAt(eventTimestamp)
      • Then the whole slashable amount for this slashing slashableAmount = activeStakeBucket.totalAssets + withdrawalsBucket_{eventEpoch + 1}.totalAssets
      • The slashedAmount is proportionally decreased from each bucket, e.g., activeStakeSlashed = slashedAmount * activeStakeBucket.totalAssets / slashableAmount
Slashing Logic

Slashing Logic - click to get more details

Off-chain updates per OnSlash

Let eventEpoch = Vault.epochAt(eventTimestamp).

  • If eventTimestamp and captureTimestamp are in different epochs:

    • slashableAmount = activeStakeBucket.totalAssets + withdrawalsBucket_{eventEpoch}.totalAssets + withdrawalsBucket_{eventEpoch + 1}.totalAssets
    • activeSlashed = slashedAmount * activeStakeBucket.totalAssets / slashableAmount
    • nextWithdrawalsSlashed = slashedAmount * withdrawalsBucket_{eventEpoch + 1}.totalAssets / slashableAmount
    • withdrawalsSlashed = slashedAmount - activeStakeSlash - withdrawalsNext
    • If withdrawalsBucket_{eventEpoch}.totalAssets < withdrawalsSlashed:
      • nextWithdrawalsSlashed += withdrawalsSlashed - withdrawalsBucket_{eventEpoch}.totalAssets
      • withdrawalsSlashed = withdrawalsBucket_{eventEpoch}.totalAssets
    • activeStakeBucket.totalAssets -= activeSlashed
    • withdrawalsBucket_{eventEpoch + 1}.totalAssets -= nextWithdrawalsSlashed
    • withdrawalsBucket_{eventEpoch}.totalAssets -= withdrawalsSlashed
  • If eventTimestamp and captureTimestamp are in the same epoch:

    • slashableAmount = activeStakeBucket.totalAssets + withdrawalsBucket_{eventEpoch + 1}.totalAssets
    • activeSlashed = slashedAmount * activeStakeBucket.totalAssets / slashableAmount
    • nextWithdrawalsSlashed = slashedAmount - activeSlashed
    • activeStakeBucket.totalAssets -= activeSlashed
    • withdrawalsBucket_{eventEpoch + 1}.totalAssets -= nextWithdrawalsSlashed

Transfer

  • event Transfer(address indexed from, address indexed to, uint256 value)
    • from - an address of the sender
    • to - an address of the recipient
    • value - a number of tokens transferred From the start, we provide two versions of the Vault:
    1. A common Vault that contains only events described above
    2. A tokenized Vault, which represents active stake shares as ERC20 tokens and, therefore, adds a Transfer event There are 3 possible cases in the sense of the Transfer event:
    3. from is zero, and to is not zero - it means minting the token
    4. from is not zero, and to is zero - it means burning the token
    5. from is not zero, and to is not zero - it means a transfer of the token In our case, the token's minting and burning are already calculated via Deposit and Withdraw events. Therefore, only transfers need off-chain handling:
    • If from0x0000000000000000000000000000000000000000 and to0x0000000000000000000000000000000000000000
      • activeStakeBucket.userShares(from) -= value
      • activeStakeBucket.userShares(to) += value

Formulas

Now, given we have all the data across all the stakers in the vault, we can get some Vault stake-related data:

activeStake(vault)=vault.activeStakeBucket.totalAssetsactiveStake(\text{vault}) = \text{vault}.activeStakeBucket.totalAssets
withdrawals(vault)=vault.withdrawalsBucket_currentEpoch.totalAssetswithdrawals(\text{vault}) = \text{vault}.withdrawalsBucket\_{currentEpoch}.totalAssets
nextWithdrawals(vault)=vault.withdrawalsBucket_currentEpoch+1.totalAssetsnextWithdrawals(\text{vault}) = \text{vault}.withdrawalsBucket\_{currentEpoch + 1}.totalAssets
TVL(vault)=activeStake(vault)+withdrawals(vault)+nextWithdrawals(vault)TVL(\text{vault}) = activeStake(\text{vault}) + withdrawals(\text{vault}) + nextWithdrawals(\text{vault})
activeSharesOf(vault,user)=vault.activeStakeBucket.userShares(user)activeSharesOf(\text{vault}, \text{user}) = \text{vault}.activeStakeBucket.userShares(\text{user})
activeShares(vault)=vault.activeStakeBucket.totalSharesactiveShares(\text{vault}) = \text{vault}.activeStakeBucket.totalShares
activeStakeOf(vault,user)=activeSharesOf(vault,user)×activeStake(vault)activeShares(vault)activeStakeOf(\text{vault}, \text{user}) = \frac{activeSharesOf(\text{vault},\text{user}) \times activeStake(\text{vault})}{activeShares(vault)}
withdrawalsOf(vault,user)=vault.withdrawalsBucketcurrentEpoch.userShares(user)×withdrawals(vault)vault.withdrawalsBucketcurrentEpoch.totalShareswithdrawalsOf(\text{vault}, \text{user}) = \frac{\text{vault}.withdrawalsBucket*{currentEpoch}.userShares(\text{user}) \times withdrawals(\text{vault})}{\text{vault}.withdrawalsBucket*{currentEpoch}.totalShares}
nextWithdrawalsOf(vault,user)=vault.withdrawalsBucketcurrentEpoch+1.userShares(user)×withdrawals(vault)vault.withdrawalsBucketcurrentEpoch+1.totalSharesnextWithdrawalsOf(\text{vault}, \text{user}) = \frac{\text{vault}.withdrawalsBucket*{currentEpoch + 1}.userShares(\text{user}) \times withdrawals(\text{vault})}{\text{vault}.withdrawalsBucket*{currentEpoch + 1}.totalShares}
slashableBalanceOf(vault,user)=activeStakeOf(vault,user)+withdrawalsOf(vault,user)+nextWithdrawalsOf(vault,user)slashableBalanceOf(\text{vault}, \text{user}) = activeStakeOf(\text{vault}, \text{user}) + withdrawalsOf(\text{vault}, \text{user}) + nextWithdrawalsOf(\text{vault}, \text{user})

Registries

OperatorRegistry

Monitor events using OperatorRegistry address

  • event AddEntity(address indexed entity)
    • entity - an address of the registered operator

Add entity to the allOperators list

NetworkRegistry

Monitor events using NetworkRegistry address

  • event AddEntity(address indexed entity)
    • entity - an address of the registered network

Add entity to the allNetworks list

VaultFactory

Monitor events using VaultFactory address

  • event AddEntity(address indexed entity)
    • entity - an address of the created Vault

Add entity to the allVaults list

Delegations

Operator-Network Opt-in

Monitor events using NetworkOptinService address

  • event OptIn(address indexed who, address indexed where)
    • who - an address of the operator who opted into
    • where - an address of the network where the operator opted into
  • event OptOut(address indexed who, address indexed where)
    • who - an address of the operator who opted out
    • where - an address of the network where the operator opted out from

On each of these events, it is needed to save if the operator is opted into the network like:

  • If OptIn
    • operatorNetworkOptIn(operator, network) = true
  • if OptOut
    • operatorNetworkOptIn(operator, network) = false

Operator-Vault Opt-in

Monitor events using VaultOptinService address

  • event OptIn(address indexed who, address indexed where)
    • who - an address of the operator who opted into
    • where - an address of the vault where the operator opted into
  • event OptOut(address indexed who, address indexed where)
    • who - an address of the operator who opted out
    • where - an address of the vault where the operator opted out from

On each of these events, it is needed to save if the operator is opted into the vault like:

  • If OptIn
    • operatorVaultOptIn(operator, network) = true
  • if OptOut
    • operatorVaultOptIn(operator, network) = false

MaxNetworkLimit

Monitor events using Vault’s Delegator address

  • event SetMaxNetworkLimit(bytes32 indexed subnetwork, uint256 amount)
    • subnetwork - a full identifier of the subnetwork (the first 40 bytes is an address of the network, the last 24 bytes are the identifier)
    • amount - a maximum network limit

Limits’ setting may perform differently depending on the Delegator’s type:

  • if NetworkRestakeDelegator (type 0)
    • maxNetworkLimit(network, identifier) = amount
    • networkLimit(network, identifier) = min(networkLimit(network, identifier), amount)
  • if FullRestakeDelegator (type 1)
    • maxNetworkLimit(network, identifier) = amount
    • networkLimit(network, identifier) = min(networkLimit(network, identifier), amount)
  • if FullRestakeDelegator (type 2)
    • maxNetworkLimit(network, identifier) = amount
    • networkLimit(network, identifier) = min(networkLimit(network, identifier), amount)

NetworkLimit (if Delegator’s type in [0, 1, 2])

Monitor events using Vault’s Delegator address

  • event SetNetworkLimit(bytes32 indexed subnetwork, uint256 amount)
    • subnetwork - a full identifier of the subnetwork (the first 40 bytes is an address of the network, the last 24 bytes are the identifier)
    • amount - a network limit

Limits’ setting may perform differently depending on the Delegator’s type:

  • if NetworkRestakeDelegator (type 0)
    • networkLimit(network, identifier) = amount
  • if FullRestakeDelegator (type 1)
    • networkLimit(network, identifier) = amount
  • if FullRestakeDelegator (type 2)
    • networkLimit(network, identifier) = amount

OperatorNetworkShares (if Delegator’s type in [0])

Monitor events using Vault’s Delegator address

  • event SetOperatorNetworkShares(bytes32 indexed subnetwork, address indexed operator, uint256 shares)
    • subnetwork - a full identifier of the subnetwork (the first 40 bytes is an address of the network, the last 24 bytes are the identifier)
    • operator - an address of the operator to set shares for
    • shares - a number of shares to set

Limits’ setting may perform differently depending on the Delegator’s type:

  • if NetworkRestakeDelegator (type 0)
    • totalOperatorNetworkShares(network, identifier) = totalOperatorNetworkShares(network, identifier) - operatorNetworkShares(network, identifier, operator) + shares
    • operatorNetworkShares(network, identifier, operator) = shares

OperatorNetworkLimit (if Delegator’s type in [1])

Monitor events using Vault’s Delegator address

  • event SetOperatorNetworkLimit(bytes32 indexed subnetwork, address indexed operator, uint256 amount)
    • subnetwork - a full identifier of the subnetwork (the first 40 bytes is an address of the network, the last 24 bytes are the identifier)
    • operator - an address of the operator to set limit for
    • amount - a limit to set

Limits’ setting may perform differently depending on the Delegator’s type:

  • if FullRestakeDelegator (type 1)
    • operatorNetworkLimit(network, identifier, operator) = amount

Formulas

Useful lists for UI

unconfirmedVaultSubnetworks(vault,network)={identifier    maxNetworkLimit(network,identifier)0,where identifier is obtained from SetMaxNetworkLimit}unconfirmedVaultSubnetworks(\text{vault}, \text{network}) = \{\text{identifier} \;|\; maxNetworkLimit(\text{network}, \text{identifier}) \neq 0, \text{where identifier is obtained from SetMaxNetworkLimit}\}
confirmedVaultSubnetworks(vault,network)={identifierunconfirmedVaultSubnetworks(vault)    networkLimit(network,identifier)0,where identifier is obtained from SetMaxNetworkLimit}confirmedVaultSubnetworks(\text{vault}, \text{network}) =\{\text{identifier} ∈ unconfirmedVaultSubnetworks(\text{vault}) \;|\; networkLimit(\text{network}, \text{identifier}) \neq 0, \text{where identifier is obtained from SetMaxNetworkLimit}\}
unconfirmedVaultNetworks(vault)={networkallNetworks    maxNetworkLimit(network,identifier)0  for at least one identifier that obtained from SetMaxNetworkLimit}unconfirmedVaultNetworks(\text{vault}) = \{\text{network} ∈ allNetworks \;|\; maxNetworkLimit(\text{network}, \text{identifier}) \neq 0 \; \text{for at least one identifier that obtained from SetMaxNetworkLimit}\}
confirmedVaultNetworks(vault)={networkunconfirmedVaultNetworks(vault)    networkLimit(network,identifier)0  for at least one identifier that can be obtained via SetMaxNetworkLimit}confirmedVaultNetworks(\text{vault}) = \{\text{network} ∈ unconfirmedVaultNetworks(\text{vault}) \;|\; networkLimit(\text{network}, \text{identifier}) \neq 0 \; \text{for at least one identifier that can be obtained via SetMaxNetworkLimit}\}
unconfirmedVaultOperators(vault)={operatorallOperators    operatorVaultOptIn(operator,vault)==true}unconfirmedVaultOperators(\text{vault}) = \{\text{operator} ∈ allOperators \;|\; operatorVaultOptIn(\text{operator}, \text{vault}) == true\}
confirmedVaultOperators(vault)={operatorunconfirmedVaultOperators(vault)    {operatorNetworkShares(network,identifier,operator)0  for at least one (network, identifier) pair,delegatorType=0operatorNetworkLimit(network,identifier,operator)0  for at least one (network, identifier) pair,delegatorType=1operator==Delegator.operator(),delegatorType=2}confirmedVaultOperators(\text{vault}) = \{\text{operator} ∈ unconfirmedVaultOperators(\text{vault}) \;|\; \begin{cases} operatorNetworkShares(\text{network}, \text{identifier}, \text{operator}) \neq 0 \; \text{for at least one (network, identifier) pair}, & delegatorType = 0 \\ operatorNetworkLimit(\text{network}, \text{identifier}, \text{operator}) \neq 0 \; \text{for at least one (network, identifier) pair}, & delegatorType = 1 \\ operator == Delegator.operator(), & delegatorType = 2 \end{cases}\}

List of operators for validator set

subnetworkVaultOperators(vault,network,identifier)={operatorallOperators    operatorVaultOptIn(operator,vault)==trueoperatorNetworkOptIn(operator,network)==true{networkLimit(vault,network,identifier)0operatorNetworkShares(vault,network,identifier,operator)0,delegatorType=0networkLimit(vault,network,identifier)0operatorNetworkLimit(vault,network,identifier,operator)0,delegatorType=1networkLimit(vault,network,identifier)0,delegatorType=2}subnetworkVaultOperators(\text{vault}, \text{network}, \text{identifier}) = \{\text{operator} ∈ allOperators \;|\; operatorVaultOptIn(\text{operator}, \text{vault}) == true \land operatorNetworkOptIn(\text{operator}, \text{network}) == true \land \begin{cases} networkLimit(\text{vault}, \text{network}, \text{identifier}) \neq 0 \land operatorNetworkShares(\text{vault}, \text{network}, \text{identifier}, \text{operator}) \neq 0, & delegatorType = 0 \\ networkLimit(\text{vault}, \text{network}, \text{identifier}) \neq 0 \land operatorNetworkLimit(\text{vault}, \text{network}, \text{identifier}, \text{operator}) \neq 0, & delegatorType = 1 \\ networkLimit(\text{vault}, \text{network}, \text{identifier}) \neq 0, & delegatorType = 2 \end{cases}\}
isOptedInNetwork(operator,network)={1,operatorNetworkOptIn(operator,network)==true0,elseisOptedInNetwork(\text{operator}, \text{network}) = \begin{cases} 1, &\quad operatorNetworkOptIn(\text{operator}, \text{network}) == true \\ 0, &\quad else \end{cases}
isOptedInVault(operator,vault)={1,operatorVaultOptIn(operator,vault)==true0,elseisOptedInVault(\text{operator}, \text{vault}) = \begin{cases} 1, &\quad operatorVaultOptIn(\text{operator}, \text{vault}) == true \\ 0, &\quad else \end{cases}
isValidOperator(vault,operator)={1,delegatorType{2,3}1,operator=delegator.operator()0,elseisValidOperator(\text{vault}, \text{operator}) = \begin{cases} 1, &\quad delegatorType ∉ \{2,3\} \\ 1, &\quad \text{operator} = delegator.operator() \\ 0, &\quad else \end{cases}
isValidNetwork(vault,network)={1,delegatorType{3}1,network=delegator.network()0,elseisValidNetwork(\text{vault}, \text{network}) = \begin{cases} 1, &\quad delegatorType ∉ \{3\} \\ 1, &\quad \text{network} = delegator.network() \\ 0, &\quad else \end{cases}
stake(vault,network,identifier,operator)=isOptedInNetwork(operator,network)×isOptedInVault(operator,vault)×{operatorNetworkShares(vault,network,identifier,operator)×min(activeStake(vault),networkLimit(vault,network,identifier))totalOperatorNetworkShares(vault,network,identifier),delegatorType=0min(activeStake(vault),min(networkLimit(vault,network,identifier),operatorNetworkLimit(vault,network,identifier,operator))),delegatorType=1isValidOperator(vault,operator)×min(activeStake(vault),networkLimit(vault,network,identifier)),delegatorType=2isValidOperator(vault,operator)×isValidNetwork(vault,network)×min(activeStake(vault),maxNetworkLimit(vault,network,identifier)),delegatorType=3stake(\text{vault}, \text{network}, \text{identifier}, \text{operator}) = isOptedInNetwork(\text{operator}, \text{network}) \times isOptedInVault(\text{operator}, \text{vault}) \times \begin{cases} \frac{operatorNetworkShares(\text{vault}, \text{network}, \text{identifier}, \text{operator}) \times \min(activeStake(\text{vault}), networkLimit(\text{vault}, \text{network}, \text{identifier}))}{totalOperatorNetworkShares(\text{vault}, \text{network}, \text{identifier})}, & delegatorType = 0 \\ \min(activeStake(\text{vault}), \min(networkLimit(\text{vault}, \text{network}, \text{identifier}), operatorNetworkLimit(\text{vault}, \text{network}, \text{identifier}, \text{operator}))), & delegatorType = 1 \\ isValidOperator(\text{vault}, \text{operator}) \times \min(activeStake(\text{vault}), networkLimit(\text{vault}, \text{network}, \text{identifier})), & delegatorType = 2 \\ isValidOperator(\text{vault}, \text{operator}) \times isValidNetwork(\text{vault}, \text{network}) \times \min(activeStake(\text{vault}), maxNetworkLimit(\text{vault}, \text{network}, \text{identifier})), & delegatorType = 3 \end{cases}
subnetworkStake(vault,network,identifier)={operatorstake(vault,network,identifier,operator),delegatorType=0min(operatorstake(vault,network,identifier,operator),activeStake(vault)),delegatorType=1_operatorstake(vault,network,identifier,operator),delegatorType=2subnetworkStake(\text{vault}, \text{network}, \text{identifier}) = \begin{cases} \sum^{}_{\text{operator}}{stake(\text{vault}, \text{network}, \text{identifier}, \text{operator})}, & delegatorType = 0 \\ \min(\sum_{\text{operator}}{stake(\text{vault}, \text{network}, \text{identifier}, \text{operator})}, activeStake(\text{vault})), & delegatorType = 1 \\ \sum\_{\text{operator}}{stake(\text{vault}, \text{network}, \text{identifier}, \text{operator})}, & delegatorType = 2 \end{cases}
userSubnetworkStake(vault,network,identifier,user)=activeStakeOf(vault,user)×subnetworkStake(vault,network,identifier)activeStake(vault)userSubnetworkStake(\text{vault}, \text{network}, \text{identifier}, \text{user}) = \frac{activeStakeOf(\text{vault}, \text{user}) \times subnetworkStake(\text{vault}, \text{network}, \text{identifier}) }{activeStake(\text{vault})}
networkStake(vault,network)=min(_identifiersubnetworkStake(vault,network,identifier),activeStake(vault))networkStake(\text{vault}, \text{network}) = \min(\sum\_{\text{identifier}}{subnetworkStake(\text{vault}, \text{network}, \text{identifier})}, activeStake(\text{vault}))
userNetworkStake(vault,network,user)=activeStakeOf(vault,user)×networkStake(vault,network)activeStake(vault)userNetworkStake(\text{vault}, \text{network}, \text{user}) = \frac{activeStakeOf(\text{vault}, \text{user}) \times networkStake(\text{vault}, \text{network}) }{activeStake(\text{vault})}
networkStakeWhole(network)=_vaultnetworkStake(vault,network)networkStakeWhole(\text{network}) = \sum\_{\text{vault}}{networkStake(\text{vault}, \text{network})}
userNetworkStakeWhole(network,user)=_vaultactiveStakeOf(vault,user)×networkStake(vault,network)activeStake(vault)userNetworkStakeWhole(\text{network}, \text{user}) = \sum\_{\text{vault}}{\frac{activeStakeOf(\text{vault}, \text{user}) \times networkStake(\text{vault}, \text{network})}{activeStake(\text{vault})}}
operatorSubnetworkStake(vault,network,identifier,operator)=stake(vault,network,identifier,operator)operatorSubnetworkStake(\text{vault}, \text{network}, \text{identifier}, \text{operator}) = stake(\text{vault}, \text{network}, \text{identifier}, \text{operator})
operatorSubnetworkPower(vault,network,identifier,operator)={operatorSubnetworkStake(vault,network,identifier,operator),delegatorType=0operatorSubnetworkStake(vault,network,identifier,operator)×subnetworkStake(vault,network,identifier)_operatoroperatorSubnetworkStake(vault,network,identifier,operator),delegatorType=1operatorSubnetworkStake(vault,network,identifier,operator),delegatorType=2operatorSubnetworkPower(\text{vault}, \text{network}, \text{identifier}, \text{operator}) = \begin{cases} operatorSubnetworkStake(\text{vault}, \text{network}, \text{identifier}, \text{operator}), & delegatorType = 0 \\ \frac{operatorSubnetworkStake(\text{vault}, \text{network}, \text{identifier}, \text{operator}) \times subnetworkStake(\text{vault}, \text{network}, \text{identifier})}{\sum\_{\text{operator}}{operatorSubnetworkStake(\text{vault}, \text{network}, \text{identifier}, \text{operator})}}, & delegatorType = 1 \\ operatorSubnetworkStake(\text{vault}, \text{network}, \text{identifier}, \text{operator}), & delegatorType = 2 \end{cases}
operatorNetworkStake(vault,network,operator)=min(_identifieroperatorSubnetworkStake(vault,network,identifier,operator),activeStake(vault))operatorNetworkStake(\text{vault}, \text{network}, \text{operator}) = \min(\sum\_{\text{identifier}}{operatorSubnetworkStake(\text{vault}, \text{network}, \text{identifier}, \text{operator})}, activeStake(vault))
operatorNetworkPower(vault,network,operator)=operatorNetworkStake(vault,network,operator)×networkStake(vault,network)_operatoroperatorNetworkStake(vault,network,operator)operatorNetworkPower(\text{vault}, \text{network}, \text{operator}) = \frac{operatorNetworkStake(\text{vault}, \text{network}, \text{operator}) \times networkStake(\text{vault}, \text{network})}{\sum\_{\text{operator}}{operatorNetworkStake(\text{vault}, \text{network}, \text{operator})}}
operatorStake(vault,operator)=min(_networkoperatorNetworkStake(vault,network,operator),activeStake(vault))operatorStake(\text{vault}, \text{operator}) = \min(\sum\_{\text{network}}{operatorNetworkStake(\text{vault}, \text{network}, \text{operator})}, activeStake(vault))
operatorStakeWhole(operator)=_vaultoperatorStake(vault,operator)operatorStakeWhole(\text{operator}) = \sum\_{\text{vault}}{operatorStake(\text{vault}, \text{operator})}