SSV Network security record

Ethereumssv.networkX

As of 1 Nov 2026, SSV Network has 2 audit reports by 2 security firms on Trustblock; the latest is by ChainSecurity, dated 20 Nov 2024. Those reports list no open critical findings.

Critical findings
No open critical findings
Across 2 reports.
Open the latest report
Your label, live
Get the label for your site

Record last updated . It holds audits and findings, contracts and incidents up to Oct 2026. Trustblock does not review code.

Audits2

Newest first

AuditSecurity firmDateScopeCritical findingsReport
SSV-DKG ToolSecurity firm: ChainSecurityDate: Scope: Not recorded (see the report)No open critical findingsOpen · chainsecurity.com
SSV.networkSecurity firm: QuantstampDate: Scope: Files named in the reportNo open critical findingsOpen · certificate.quantstamp.com

Findings33

Statuses are the security firm’s own, from each report.

SeverityOpenAcknowledgedFixed
Critical000
High003
Medium035
Low2155
MediumUse of Discouraged Asymmetric Encryption PrimitiveSSV-DKG Tool · ChainSecurity · 20 Nov 2024Acknowledged

The report gives no description here.

Open the report
MediumDelayed Liquidation Results in Insufficient SSV BalanceSSV.network · Quantstamp · 21 Jul 2023Acknowledged

Liquidations ensure that clusters have an adequate amount of SSV deposited to cover unclaimed network and operator fees. This is critical as operators continuously receive SSV rewards regardless of the cluster's SSV balance. In the case where a cluster's SSV balance falls below the liquidation threshold and is not liquidated, the operators risk not being able to withdraw their earnings as the SSV balance of `SSVNetwork` is insufficient. Additionally, the cluster may remain insolvent upon reactivation due to mismatch between the operators' balances and the cluster's balance.

Open the report
MediumFront-Running Calls to `registerOperator()` and `registerValidator()`SSV.network · Quantstamp · 21 Jul 2023Acknowledged

When an operator calls `registerOperator()`, the operator's `publicKey` and `fee` amounts are passed as arguments. Once `registerOperator()` is called, the operator is registered with its `publicKey`, and the operator owner is set as the caller. Since the operator's `publicKey` refers to the operator's SSV node and differs from the caller's public key, there is no way of verifying that the caller is the actual owner of the operator's `publicKey`. Therefore, a malicious user could see a `registerOperator()` call in the pending transaction pool and front-run the transaction with the operator's `publicKey`. The same vulnerability is present with validators when calling `registerValidator()`. While the caller of `registerOperator()` or `registerValidator()` needs prior authorization from the `owner` via the `SSVNetwork.setRegisterAuth()` function, any registered operator or validator can front-run calls to `registerOperator()` or `registerValidator()` that are from other authorized users.

Open the report
LowApplication Monitoring Can Be Improved by Emitting More EventsSSV.network · Quantstamp · 21 Jul 2023Acknowledged

In order to validate the proper deployment and initialization of the contracts, it is a good practice to emit events. Also, any important state transition can be logged, which is beneficial for monitoring the contract, and also tracking eventual bugs, or hacks. Below we present a non-exhaustive list of events that could be emitted to improve application management: 1. `OperatorLib.updateSnapshotSt()`: `operator.snapshot.*`. 1. `OperatorLib.updateOperators()`: `operator.validatorCount`. 1. `ProtocolLib.updateNetworkFee()`: `StorageProtocol.networkFeeIndex`, `StorageProtocol.networkFeeIndexBlockNumber` and `StorageProtocol.networkFee`. 1. `ProtocolLib.updateDAOEarnings()`: `StorageProtocol.daoBalance` and `StorageProtocol.daoIndexBlockNumber`. 1. `ProtocolLib.updateDAO()`: `StorageProtocol.daoValidatorCount`. 1. `ClusterLib.updateBalance()`: `cluster.balance`. 1. `ClusterLib.updateClusterData()`: `cluster.index` and `cluster.networkFeeIndex`.

Open the report
LowBlock Timestamp ManipulationSSV.network · Quantstamp · 21 Jul 2023Acknowledged

At `SSVNetwork.sol#770`, comparisons are made against `block.timestamp`. Projects may rely on block timestamps for various purposes. Given that this project may, in principle, be deployed on any EVM chain, it is important to note that different networks may impose different requirements for their validators when it comes to setting the timestamp of a block, and attackers may be able to manipulate timestamps for their own purposes. If a smart contract relies on a timestamp, it must take this into account.

Open the report
LowFees Charged for Invalid SetupSSV.network · Quantstamp · 21 Jul 2023Acknowledged

If there are enough operators removed for a validator, the consensus between operators may be affected for the particular validator. For example, if there are four operators, and two operators are removed, consensus cannot be reached among the operators. The validator will become idle and lose out on block proposal and attestation rewards. Based on the current implementation, the validator still owes payments to any active operators even though the setup is invalid.

Open the report
LowInactive Operators Can Lead to Insufficient ConsensusSSV.network · Quantstamp · 21 Jul 2023Acknowledged

The `SSVNetwork.removeOperator()` function allows operators to remove themselves from the clusters they were previously operating for. Although this action causes the operators to stop receiving SSV rewards, the clusters are not updated to reflect the operator's removal. As a result, if sufficiently many operators are removed, consensus may not be reached. In addition, if an operator stops running an operator node without calling `removeOperator()`, they will no longer contribute to the consensus threshold, but they will still receive SSV rewards from the cluster owner. Based on the current implementation, the validator still owes payments to any active operators even though the setup is invalid. Therefore, validators must track the performance of the operators they use to ensure the success of their validator and maximize their rewards.

Open the report
LowIncompatible with Deflationary TokensSSV.network · Quantstamp · 21 Jul 2023Acknowledged

The contracts are not designed to accommodate deflationary tokens when accepting token transfers. If a user transfers funds that incur a fee on transfer during `deposit()` or `reactivate()`, the contract will report that the user has deposited more funds than they actually sent. This can cause issues during withdrawal. This issue is provided as informational if payments are updated to accept other tokens.

Open the report
LowInconsistent Use of `shrink()` and `expand()`SSV.network · Quantstamp · 21 Jul 2023Acknowledged

The current implementation of the `updateNetworkFee()` function in the code snippet is emitting the entire network `fee` in the `NetworkFeeUpdated` event, despite the shrunken `fee` being saved in the `network` struct. This could lead to confusion and misinterpretation of the actual network fee. ``` Network memory network_ = network; DAO memory dao_ = dao; dao_.updateDAOEarnings(network.networkFee); dao = dao_; network_.networkFeeIndex = NetworkLib.currentNetworkFeeIndex(network_); network_.networkFeeIndexBlockNumber = uint64(block.number); emit NetworkFeeUpdated(network_.networkFee.expand(), fee); network_.networkFee = fee.shrink(); network = network_; ``` Inconsistent uses of shrunken fees were found in the following functions: 1. `fee` in `SSVNetwork.declareOperatorFee()` 2. `fee` in `SSVNetwork.reduceOperatorFee()` 3. `fee` in `SSVNetwork.registerOperator()` 4. `fee` in `SSVNetwork.updateNetworkFee()` 5. `amount` in `SSVNetwork.updateMinimumLiquidationCollateral()` 6. `fee` in `SSVNetwork.declareOperatorFee()` 7. `fee` in `SSVNetwork.reduceOperatorFee()`

Open the report
LowKeyshare Reuse Could Lead to Compromising Validator Private KeySSV.network · Quantstamp · 21 Jul 2023Acknowledged

The project uses Shamir Secret Sharing to split validator private keys into encrypted key shares for distribution to operators. However, suppose an operator is removed from a cluster and later added back in. The case where the private key would be split into the same key shares as in the initial configuration and a different encrypted key share would be sent to an operator should be avoided, as this may result in an operator potentially accumulating the quorum number of key shares, compromising the validator private key.

Open the report
Show 8 more
LowMissing Input ValidationSSV.network · Quantstamp · 21 Jul 2023Acknowledged

It is crucial to validate inputs, even if the inputs come from trusted addresses, to avoid human error. A lack of robust input validation can only increase the likelihood and impact in the event of mistakes. The following is the list of places that can potentially benefit from a stricter input validation: 1. `SSVNetwork.sol#L110`: the `minimumBlocksBeforeLiquidation_` of the `__SSVNetwork_init_unchained()` can be less than `MINIMAL_LIQUIDATION_THRESHOLD`. 1. `SSVNetwork.sol#L173`: the `recipientAddress` of the `setFeeRecipientAddress()` should not be zero address. 1. `SSVNetwork.sol#L180`: the `keccak256` of `publicKey` of the `registerValidator()` should not be zero bytes. 1. `SSVNetwork.sol#L180`: the length of `shares` of the `registerValidator()` should match the length of `operatorIds`. 1. `SSVNetwork.sol#L604`: the `amount` of `withdrawNetworkEarnings()` should be greater than zero. 1. **(Fix Review)** `ProtocolLib.sol#18`: the `fee` of the `updateNetworkFee()` function not checked to be non-zero or otherwise reasonably bound. 1. **(Fix Review)** `ProtocolLib.sol#L38`: the `deltaValidatorCount` of the `updateDAO()` function is not checked to be non-zero or otherwise reasonably bound. 1. **(Fix Review)** `SSVNetworkViews.sol#L58:` the `operatorId` of the `getOperatorById()` function is not checked to be an existing operator. 1. **(Fix Review)** `SSVDAO.sol#L45`: the `percentage` of the `updateOperatorFeeIncreaseLimit()` function is not checked to be non-zero or smaller than `PRECISION_FACTOR`.

Open the report
LowOperator Fee Cannot Increase Once Set to ZeroSSV.network · Quantstamp · 21 Jul 2023Acknowledged

The `_declareOperatorFee()` function calculates the maximum allowed fee increase based on the current `operatorFee` and the maximum allowed fee increase percentage `operatorMaxFeeIncrease`. If the new fee is greater than the maximum allowed fee increase, it reverts with a `FeeExceedsIncreaseLimit` error. The operator fee can be set to zero in `declareOperatorFee()` or reduced to zero with `reduceOperatorFee()` and due to `operatorMaxFeeIncrease`, increasing the operator fee will become impossible once the operator fee is set to zero.

Open the report
LowPrivileged RolesSSV.network · Quantstamp · 21 Jul 2023Acknowledged

All privileged permissions should be clearly documented for users. The privileged permissions of each contract are documented below. `SSVNetwork` and `SSVNetworkViews` are upgradeable contracts that can have their implementation contracts swapped out at any time through `upgradeTo()` function by the contract owner. - `SSVNetwork.removeValidator()` can only be called by `_validatorPKs[hashedValidator].owner` - `SSVNetwork.liquidate()` can be called by a cluster's owner when `isLiquidatable()` returns false The following are all cases of owner privileges: - `SSVNetwork.updateNetworkFee()` - `SSVNetwork.withdrawNetworkEarnings()` - `SSVNetwork.updateOperatorFeeIncreaseLimit()` - `SSVNetwork.updateDeclareOperatorFeePeriod()` - `SSVNetwork.updateExecuteOperatorFeePeriod()` - `SSVNetwork.updateLiquidationThresholdPeriod()` - `SSVNetwork.updateMinimumLiquidationCollateral()` - **(Fix Review)** `SSVNetwork.setRegisterAuth()`: If a validator is authorized, calls `SSVNetwork.registerValidator()`, then has their authorization revoked, the validator is still active and can call `SSVNetwork.reactivate()` if the cluster becomes inactive. - **(Fix Review)** `SSVNetwork.upgradeModule()`: This privileged function has a high exploit risk if the `owner` is compromised. If a module is upgraded to a malicious contract, the malicious contract could drain the `SSVNetwork` contract of all funds.

Open the report
LowRenouncable OwnershipSSV.network · Quantstamp · 21 Jul 2023Acknowledged

If the owner renounces their ownership, all ownable contracts will be left without an owner. Consequently, any function protected by the `onlyOwner` modifier will no longer be able to be executed.

Open the report
LowRisk of Killing UpgradesSSV.network · Quantstamp · 21 Jul 2023Acknowledged

The UUPS pattern was chosen for the upgradeable contracts. One of the drawbacks of using such a pattern is that if a future implementation does not implement the `upgradeTo()` function, then upgrades for the contracts have effectively been killed.

Open the report
LowSame Validator Public Key Registered by Different CallersSSV.network · Quantstamp · 21 Jul 2023Acknowledged

When registering a validator, the validator's `publicKey` and the caller's address are hashed to create a validator ID, which is considered the unique identifier for the validator and is used as the key in the `validatorPKs` mapping. Since the `registerValidator()` function does not verify that a validator's `publicKey` is unique when registering, multiple different users can call `registerValidator()` with the same `publicKey` but have unique validator identifiers.

Open the report
LowUncapped State VariablesSSV.network · Quantstamp · 21 Jul 2023Acknowledged

There are numerous state variables within `SSVNetwork` that do not have a lower or upper bound limit. While the functions that update these state variables are only accessible to the owner, an improper configuration could lead to a negative user experience or loss of funds. 1. `operatorMaxFeeIncrease`: No upper bound limit. If set to a large value, operators could increase their fee substantially after `declareOperatorFeePeriod` has passed. Unaware cluster owners are then at risk of paying high operator fees or liquidation. 2. `declareOperatorFeePeriod`: No lower bound limit. If set to a small value, operators could update their fee before cluster owners have enough time to respond. 3. `executeOperatorFeePeriod`: No lower bound limit. If set to a small value, operators would not have an adequate amount of time to execute their fee update. 4. `minimumBlocksBeforeLiquidation`: No upper bound limit. If set to a large value, all clusters are at risk for liquidation. 5. `minimumLiquidationCollateral`: No upper bound limit. If set to a large value, all clusters are at risk for liquidation.

Open the report
LowUse of Unsafe Transfer FunctionsSSV.network · Quantstamp · 21 Jul 2023Acknowledged

Functions `CoreLib.transferBalance()` and `CoreLib.deposit()` use the ERC20 functions `transfer()` and `transferFrom()` to transfer funds from the underlying token (`SSVStorage.token`). However, there [exist tokens that do not return a value](https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca) and would be handled wrongly in the given context.

Open the report

Contracts

No deployed address is recorded for these audits.

The reports name a repository or files. Open a report to see its scope.

The repositories and files the reports name

Show this on your site

Is this your project? Show this record on your own website. The label states what the record holds, links to this page and updates by itself. It is free and needs no sign-in.

Content

Facts

Automatic: the three strongest facts of this project’s own record (its last audit and two more), highlighted. They update with the record. Picking a fact turns Automatic off.

Fixed as
Language

Style

Layout
Theme
Accent
Corners

Format

Size
Date
Embed as
HTML
<head>
<script src="https://widget.trustblock.run/project-widget.min.js" defer></script>
</head>
<body>
<div
data-tb-project-widget
data-tb-project-slug="ssv-network"
></div>
</body>

Paste the code where the label should appear. It uses no API credit and updates by itself.

Something wrong on this page? A missing report, a wrong date, a finding that was fixed since. Tell us and we check it against its source.

Tell us