Skip to content
Quantix Security Labs

Risk summary

State at remediation commit 41f0c7a9e2d5

Findings
7
Critical and high
1
Open or partial
0
Remediation
100%

Findings by severity

  • Critical0
  • High1
  • Medium3
  • Low2
  • Informational1

Remediation statusAnalysis

  • Resolved6
  • Partially resolved0
  • Acknowledged1
  • Open0

Helion Protocol

Liquid Staking

Document
QX-TSA-2026-009 · v1.0
Type
Smart Contract Audit
Review
10 Nov 2025 – 5 Dec 2025
Published
12 Jan 2026
Ecosystems
Ethereum
Languages
Solidity
Risk Index
AA87.7
Assessment contents · 12 sections

01

Assessment overview

Helion Protocol lets users stake ETH without running validators. Deposits mint hETH, a rebasing token whose balances grow as validator rewards are reported. Approved node operators run the validators, and an oracle committee reports beacon-chain balances once per day. Quantix reviewed the pool, token, registry, oracle and withdrawal vault at the commit in this report.

The single high-severity finding concerned the oracle committee: the quorum could be set, or left by member removals, below a majority of members, letting a minority finalise balance reports that drive every rebase. Medium-severity findings covered rounding in withdrawal-batch finalisation that could leave the last claimant unable to withdraw, deposit front-running by node operators, and a timing mismatch between oracle reference slots and the vault balance.

All findings except a documented one-to-two wei rounding behaviour were fixed and verified. A formal specification of share accounting and quorum rules accompanies this report; all specified properties hold on the remediation commit.

Helion's main residual risks are those inherent to liquid staking: correlated slashing across operators, oracle committee honesty, and the time withdrawals take on the consensus layer.

02

Technical analysis: protocol architecture

StakingPool holds buffered ETH, mints shares to depositors and batches 32 ETH deposits to validators registered by operators in OperatorRegistry. hETH balances are computed as shares × totalPooledEther / totalShares, so a rebase changes totalPooledEther without touching individual records.

Every 24 hours, members of the AccountingOracle committee submit a report for a reference slot: total validator balance, number of exited validators, and the withdrawal-vault balance. When a quorum of identical reports arrives, the pool applies it, bounded by sanity checks on the implied annual rate.

Withdrawals are requested in hETH, queued as NFTs, and finalised in batches when the oracle report shows enough ETH has arrived in the WithdrawalVault through EIP-4895 withdrawals.

Trusted· 4

Assumed to behave as specified; compromise is out of the threat model.

  • StakingPoolShare accounting, deposits, withdrawal queue
  • hETHRebasing token interface over shares
  • OperatorRegistryOperator keys and limits
  • AccountingOracleApplies committee reports
trust boundary

Semi-trusted· 2

Trusted for liveness or within bounds; misbehaviour is partly modelled.

  • Oracle committee membersReport validator balances
  • Node operatorsRun validators with registered keys
trust boundary

Untrusted· 1

May act adversarially; every input is validated.

  • Stakers and integratorsDeposit, transfer and withdraw
Components grouped by trust level. Calls that cross a trust boundary are where the review concentrated input validation and authorisation checks.

Trust assumptions

  • A majority of oracle committee members report honestly.
  • Node operators do not collude to slash validators deliberately; misbehaviour is bounded by deposit limits.
  • The consensus layer processes withdrawals per its specification.
  • Governance changes pass through a timelock and are monitored.

03

Scope

Staking pool, rebasing hETH, operator registry, accounting oracle and withdrawal vault. 2,486 nSLOC of Solidity.

Repository
github.com/example-org/helion-core
Review effort
Three reviewers over twenty working days, with a parallel specification and verification track
Reviewed commit
b8e4d2a07f1c935e6d0a4b28c71f9e3d5a6b0c2e
Remediation commit
41f0c7a9e2d58b36c1e07a4d9f2b6e8c03a5d7b1
Files and components in scope
PathDescriptionnSLOC
contracts/StakingPool.solDeposits, share accounting, rebases and the withdrawal queue934
contracts/token/hETH.solRebasing liquid staking token over pool shares312
contracts/OperatorRegistry.solNode operators, signing keys and deposit limits486
contracts/oracle/AccountingOracle.solCommittee reports of validator balances402
contracts/WithdrawalVault.solReceives beacon-chain withdrawals88
contracts/DepositGuard.solDeposit-root checks before staking (added during remediation)264
Total6 items2,486

Out of scope

  • Validator client software and node-operator infrastructure
  • Off-chain oracle daemons that compute reports
  • The Ethereum deposit contract and consensus layer
  • Governance token and DAO voting contracts

04

Threat model

Each threat lists the actor, the vector and the mitigation, and links to the findings that realised it in the reviewed code.

Assets at risk

  • Staked ETH and buffered deposits
  • Correct hETH supply and balances
  • Withdrawal queue solvency
  • Validator withdrawal credentials

Actors

  • Colluding oracle minoritySemi-trustedSubmits false balance reports
  • Malicious node operatorSemi-trustedFront-runs deposits with its own withdrawal credentials
  • Rebase arbitrageurUntrustedTimes deposits and withdrawals around reports
  • Committee manager roleTrustedAdds and removes members, sets quorum
Threats, vectors, mitigations and related findings
ThreatActorVectorMitigationFindings
Inflate or deflate hETH supply through a false reportColluding oracle minorityQuorum below a majorityQuorum floor of a strict majority on every membership change; rebase boundsHP-01
Leave late claimants unable to withdrawRoundingBatch reservation rounding differs from claim roundingStore per-request amounts at finalisationHP-02
Steal a 32 ETH depositMalicious node operatorPre-deposit with own withdrawal credentialsGuardian-signed deposit root checkHP-04
Extract value around rebasesRebase arbitrageurReward double counting from vault timingReport vault balance at the reference slotHP-05

05

Findings

Severity

7 findings

HP-01HighResolvedGovernance manipulation

Oracle quorum can fall below a majority of committee members

contracts/oracle/AccountingOracle.sol:L94–L131 (setQuorum, removeMember, _submitReport)

Likelihood
Medium
Impact
High
Weakness
CWE-285
Description

Each report is finalised when quorum members have submitted the same report hash for a frame. setQuorum(q) only requires q > 0, and removeMember() decrements the member count without re-checking the quorum. With seven members and a quorum of four, removing three members leaves four members and a quorum of four, which is fine; but a later setQuorum(2) or an initial misconfiguration lets two members finalise reports alone.

Reports drive totalPooledEther, so a finalised false report changes every hETH balance. The pool applies sanity bounds to the implied annual rate, but the bounds were generous (an annualised 27% positive rebase) and a negative report is bounded only by the slashing limit.

The defect is that the safety of the oracle depends on an invariant (quorum is a strict majority) that the contract does not enforce.

Preconditions
  • A quorum set below a strict majority, through configuration error or a compromised manager role.
  • Collusion or compromise of that many committee members.
Exploit scenario
  1. 1.The committee manager role (a 3-of-5 multisig) lowers the quorum to two during a member rotation and forgets to raise it.
  2. 2.Two colluding members submit a report overstating validator balances within the 27% annualised bound.
  3. 3.The pool applies a positive rebase. The members, who hold hETH, request withdrawals at the inflated rate before the next honest report corrects it.
Impact

Value transferred from stakers to the colluding members, bounded by the rebase limit per report; repeated reports compound the loss.

Recommendation

Enforce quorum ≥ members / 2 + 1 in setQuorum, addMember and removeMember, and tighten the positive rebase bound to a realistic annualised rate.

Fix
contracts/oracle/AccountingOracle.sol (remediation commit)diff
   function setQuorum(uint256 q) external onlyRole(MANAGE_MEMBERS_ROLE) {-      require(q > 0, "quorum");+      _requireMajority(q, members.length);       quorum = q;   }    function removeMember(address m) external onlyRole(MANAGE_MEMBERS_ROLE) {       _remove(m);+      if (quorum > members.length) quorum = members.length;+      _requireMajority(quorum, members.length);   }++  function _requireMajority(uint256 q, uint256 n) internal pure {+      if (q < n / 2 + 1 || q > n) revert QuorumNotMajority(q, n);+  }
Resolution

Fixed. The quorum is validated on every membership change, and the positive rebase bound was lowered to an annualised 10%.

HP-02MediumResolvedPrecision and rounding

Batch finalisation reserves less ETH than the sum of claims, so the last claimant in a batch cannot withdraw

contracts/StakingPool.sol:L611–L668 (_finalizeBatch, claimWithdrawal)

Likelihood
Medium
Impact
Medium
Weakness
CWE-1339
Description

When a batch of withdrawal requests is finalised, the pool reserves floor(sumShares × rate / PRECISION) ETH for the whole batch, where rate is the share rate applied to the batch. Each claim later computes its own amount with Math.mulDiv(requestShares, rate, PRECISION, Math.Rounding.Ceil); the developers rounded claims up so that no user would receive less than their shares are worth.

The two calculations round in opposite directions. Each claim can exceed its exact share of the reservation by up to one wei, while the reservation itself is rounded down, so the sum of claims in a batch can exceed the reserved ETH by up to the number of requests in the batch. Claims are paid first come, first served out of lockedEther.

The shortfall is tiny, but its effect is binary: the last claimant in the batch finds the reservation exhausted and the transaction reverts. The user is blocked until someone donates the missing wei or a later batch happens to over-reserve.

Preconditions
  • A batch in which at least one request's conversion is not exact, which is the normal case.
Exploit scenario
  1. 1.A batch of 400 requests is finalised. Rounding each claim up makes their sum 3 wei larger than the rounded-down reservation.
  2. 2.The first 399 claimants withdraw normally.
  3. 3.The final claim reverts with "insufficient reserved ether" and remains blocked.
Impact

Denial of withdrawal for affected users until manual intervention. Invariant P4 (queue solvency) is violated.

Recommendation

Compute each request's claimable ETH once at finalisation with a single rounding direction (down), reserve exactly the sum of those stored amounts, and pay claims from the stored value.

Fix
contracts/StakingPool.sol (remediation commit)diff
-      uint256 reserve = sumShares * rate / PRECISION;+      uint256 reserve;+      for (uint256 id = first; id <= last; ++id) {+          Request storage r = requests[id];+          uint256 amount = Math.mulDiv(r.shares, rate, PRECISION); // floor, stored once+          r.claimable = uint128(amount);+          reserve += amount;+      }       lockedEther += reserve; ...-      uint256 amount = Math.mulDiv(r.shares, batchRate[r.batch], PRECISION, Math.Rounding.Ceil);+      uint256 amount = r.claimable;
Resolution

Fixed. Claims are paid from stored per-request amounts and invariant P4 holds on the remediation commit.

HP-03LowAcknowledgedPrecision and rounding

Transfers of hETH can deliver one to two wei less than the requested amount

contracts/token/hETH.sol:L144–L172 (transfer, transferFrom, getSharesByPooledEth)

Likelihood
Medium
Impact
Low
Weakness
CWE-682
Description

hETH balances are derived from shares. A transfer of amount converts to shares with amount × totalShares / totalPooledEther, rounding down, so the recipient's balance increases by slightly less than amount and the sender may retain one or two wei after "transferring everything".

This is inherent to rebasing tokens built over shares. It does not lose value for the protocol, but integrations that assume balanceOf(recipient) increases by exactly amount (vaults, bridges, accounting that compares balances) can fail or record dust mismatches.

Preconditions
  • An integration that relies on exact transfer amounts.
Exploit scenario
  1. 1.A vault records a deposit of 10 hETH but receives 9.999999999999999999 hETH; its strict accounting check reverts.
Impact

Integration failures and dust balances; no loss to stakers.

Recommendation

Document the behaviour prominently, provide transferShares() for integrators, and recommend a non-rebasing wrapper for DeFi use.

Resolution

Acknowledged. Documented in the integration guide; transferShares() and a wrapped non-rebasing token are available.

HP-04MediumResolvedBusiness logic

Node operators can front-run pool deposits with their own withdrawal credentials

contracts/StakingPool.sol:L402–L451 (depositBufferedEther), contracts/OperatorRegistry.sol:L210

Likelihood
Low
Impact
High
Weakness
CWE-362
Description

The deposit contract keys validators by public key. If a deposit for a given public key already exists, subsequent deposits for the same key top up that validator and keep the withdrawal credentials of the first deposit.

An operator registers a signing key with Helion, observes the pool's 32 ETH deposit for that key in the mempool, and front-runs it with a 1 ETH deposit for the same key using withdrawal credentials it controls. The pool's deposit then tops up a validator whose withdrawals go to the operator.

Operators are permissioned, which lowers likelihood, but each successful front-run diverts a full 32 ETH deposit.

Preconditions
  • A malicious or compromised node operator with registered keys.
Exploit scenario
  1. 1.The operator sees depositBufferedEther pending with its key.
  2. 2.It submits a 1 ETH deposit for the same key with its own withdrawal credentials and a higher priority fee.
  3. 3.The pool's 32 ETH lands on the operator-controlled validator.
Impact

Loss of 32 ETH per front-run deposit.

Recommendation

Before each deposit, check the deposit contract's get_deposit_root() against a root signed by a quorum of independent guardians, so that any deposit in between invalidates the batch.

Fix
contracts/StakingPool.sol (remediation commit)diff
-  function depositBufferedEther(uint256 count) external onlyRole(DEPOSITOR_ROLE) {+  function depositBufferedEther(uint256 count, bytes32 depositRoot, GuardianSig[] calldata sigs) external {+      if (DEPOSIT_CONTRACT.get_deposit_root() != depositRoot) revert DepositRootChanged();+      depositGuard.verify(depositRoot, count, block.number, sigs); // quorum of guardians
Resolution

Fixed with a new DepositGuard contract requiring signatures from four of six guardians over the current deposit root.

HP-05MediumResolvedBusiness logic

Withdrawal-vault ETH arriving after the reference slot is counted as rewards

contracts/StakingPool.sol:L702–L748 (handleOracleReport), contracts/WithdrawalVault.sol:L31

Likelihood
High
Impact
Low
Weakness
CWE-841
Description

Reports describe the validator balance at a reference slot. When applying a report, the pool pulls the entire current balance of the WithdrawalVault, which also includes ETH from withdrawals processed between the reference slot and the moment the report lands on-chain (often several hours).

The validator balance in the report already excludes those withdrawals only if they happened before the reference slot. ETH that arrived later is therefore counted twice in the next report cycle and once as an unexplained reward now, producing an inflated rebase followed by a smaller one. Arbitrageurs who track withdrawals can deposit before an inflated report and request withdrawal after it.

Preconditions
  • Beacon-chain withdrawals arriving between the reference slot and report submission.
Exploit scenario
  1. 1.An observer sees a large batch of exits processed after the reference slot, deposits before the report, and requests withdrawal at the inflated rate.
Impact

Small, repeated transfers of value from long-term stakers to rebase arbitrageurs.

Recommendation

Include the vault balance at the reference slot in the report and transfer only that amount when applying it.

Fix
contracts/StakingPool.sol (remediation commit)diff
-      uint256 withdrawn = address(withdrawalVault).balance;-      withdrawalVault.withdrawWithdrawals(withdrawn);+      uint256 withdrawn = report.withdrawalVaultBalance; // at reference slot+      withdrawalVault.withdrawWithdrawals(withdrawn);
Resolution

Fixed. Reports now carry the vault balance at the reference slot.

HP-06LowResolvedKey management

Pause authority held by a single externally owned account

Deployment configuration: PAUSE_ROLE on StakingPool and hETH

Likelihood
Low
Impact
Medium
Weakness
CWE-284
Description

Pausing stops deposits, transfers and withdrawals. The role is held by one EOA used by the on-call engineer. Fast pausing is valuable in an incident, but a single key can also freeze user funds indefinitely if compromised, and unpausing requires the same key.

Preconditions
  • Compromise or loss of the pause key.
Exploit scenario
  1. 1.An attacker with the key pauses hETH transfers during market stress, blocking exits.
Impact

Temporary freezing of user funds; no direct theft.

Recommendation

Move pausing to a guardian multisig with a low threshold and limit pause duration, with unpausing through governance.

Resolution

Fixed. Pausing moved to a 2-of-5 guardian multisig; pauses expire after 14 days unless renewed by governance.

HP-07InformationalResolvedCode quality

Quorum and membership changes are not emitted as events

contracts/oracle/AccountingOracle.sol

Likelihood
Low
Impact
Low
Description

Membership and quorum changes update storage without events, so monitoring cannot detect the configuration change behind HP-01 without polling storage.

Preconditions
  • None; observability only.
Exploit scenario
  1. 1.Not exploitable.
Impact

Reduced ability to detect governance changes to the oracle.

Recommendation

Emit MemberAdded, MemberRemoved and QuorumChanged.

Resolution

Fixed.

06

Severity

7findings
  • Critical0 · 0%
  • High1 · 14%
  • Medium3 · 43%
  • Low2 · 29%
  • Informational1 · 14%

By vulnerability class

  • Business logic2
  • Precision and rounding2
  • Code quality1
  • Governance manipulation1
  • Key management1

Likelihood and impact

Each finding placed by the likelihood of its preconditions and the impact of exploitation.

Findings by likelihood (columns) and impact (rows)
Impact ↓ / Likelihood →LowMediumHigh
High
0
Medium
0
Low

07

Remediation

6 of 7 findings are resolved, 1 acknowledged, 0 partially resolved and 0 open at remediation commit 41f0c7a9e2d5.

Remediation progress100%

Resolved and acknowledged findings count fully; partially resolved findings count half.

100%remediated
  • Resolved6 · 86%
  • Partially resolved0 · 0%
  • Acknowledged1 · 14%
  • Open0 · 0%
Findings by severity and remediation status
SeverityResolvedPartially resolvedAcknowledgedOpenTotal
Critical00000
High10001
Medium30003
Low10102
Informational10001
All findings60107

Residual items

  • HP-03LowAcknowledgedAcknowledged. Documented in the integration guide; `transferShares()` and a wrapped non-rebasing token are available.
  • ResolvedFixed and verified in the remediation review.
  • Partially resolvedMitigated; the residual risk is documented.
  • AcknowledgedAccepted by the protocol team with a stated rationale.
  • OpenNot yet addressed at the reviewed remediation commit.

08

Formal verification

Share accounting, oracle quorum and withdrawal-queue solvency were specified as rules and checked on the remediation commit. Two rules failed on the original commit and led to HP-01 and HP-02. All rules hold after remediation; a liveness property about report timing was out of reach of the prover and is covered by tests.

Tool: CVL-style specification checked with an SMT-based prover; Halmos for arithmetic lemmas

  • P1ProvedThe sum of shares across all holders equals totalShares after any operation.
  • P2ProvedA report is applied only after a strict majority of current committee members submitted the same report hash.Violated on the original commit (HP-01).
  • P3ProvedA single report changes totalPooledEther by at most the configured annualised positive bound or the slashing-bounded negative limit.
  • P4ProvedETH reserved for finalised withdrawal requests is at least the sum of their unclaimed amounts.Violated on the original commit by up to n wei per batch (HP-02).
  • P5ProvedA holder's balance changes only through transfers, rebases or withdrawals initiated by the holder.
  • P6InconclusiveReports are applied in order of reference slot and at most once per frame.Temporal property; covered by integration tests.

A proved property holds for every execution of the model under its stated assumptions. Fuzzing and property-based results are evidence, not proofs, and are recorded as inconclusive.

09

Recommendations

  1. 01

    Monitor oracle configuration and reports

    Alert on quorum and membership changes, on reports near the rebase bounds, and on disagreeing member submissions.

  2. 02

    Diversify node operators and limit concentration

    Keep per-operator deposit limits low enough that a single operator's slashing or misbehaviour is absorbed by the buffer.

  3. 03

    Publish integration guidance for rebasing behaviour

    Make the wrapped token the default for DeFi integrations and document HP-03 for those that integrate hETH directly.

  4. 04

    Keep the formal specification in CI

    Re-run the accounting and quorum rules on every change to the pool and oracle.

10

Methodology and limitations

  1. 01Specification workshop covering share accounting, report lifecycle and the withdrawal queue
  2. 02Manual review of all in-scope contracts by two reviewers each
  3. 03Invariant fuzzing of share accounting under rebases, slashing and batched withdrawals
  4. 04Formal specification of accounting and quorum rules checked with an SMT-based prover
  5. 05Scenario analysis of oracle collusion, operator front-running and rebase timing
  6. 06Remediation review including the new DepositGuard contract

Severity classification

Critical
Direct loss of funds or permanent loss of control is achievable with little or no precondition.
High
Material loss or protocol disruption is achievable under realistic conditions.
Medium
Limited loss, degraded functionality, or impact that depends on specific conditions.
Low
Minor impact, defence-in-depth gaps, or issues with unlikely preconditions.
Informational
Code quality, documentation or best-practice observations without direct security impact.

Limitations

  • Off-chain oracle daemons, validator clients and operator infrastructure were out of scope.
  • Consensus-layer behaviour was assumed to follow the published specifications.
  • Formal results hold for the stated rules and the modelled environment; external calls to the deposit contract were summarised.

No assessment can show that a system is free of vulnerabilities. This research assessment reflects the code at the commits listed. Quantix methodology

11

Technical appendix

Tools

  • FoundryUnit, fork and invariant tests
  • SMT-based prover (CVL-style rules)Accounting, quorum and queue-solvency properties
  • HalmosArithmetic lemmas for share conversion
  • SlitherStatic analysis
Reviewed files (SHA-256) · 5 files
SHA-256 hashes of reviewed files
FileSHA-256
contracts/StakingPool.sol0095bdf38d1e5cb0d812578ff9efe7ea180539eb49b23b6f17d207cdc52fbc23
contracts/token/hETH.sol5db79da03827850d55ec1f16ef11562f55ad04e2085b5dd3645fae82c6a7d9c5
contracts/OperatorRegistry.sol3f463807e94d47ef7b6cce00c24982cbb94f1711b5f6073a75b44fe5f143b221
contracts/oracle/AccountingOracle.sol7b3320ed8a642fbb838ec7fac9c52334fd98c4b5899b5c7ea9105b10a08b7eb6
contracts/WithdrawalVault.solf68726c63886a5888bd73ee5eb800006d879ea8cad49552c255a7337a824ff6a

Notes

  • File hashes are SHA-256 digests of the reviewed sources at the audited commit.

Technical references

  1. 1.CWE-285: Improper Authorization (opens in a new tab)
  2. 2.CWE-1339: Insufficient Precision or Accuracy of a Real Number (opens in a new tab)
  3. 3.EIP-20: Token Standard (opens in a new tab)
  4. 4.CWE-682: Incorrect Calculation (opens in a new tab)
  5. 5.Ethereum consensus specifications (opens in a new tab)
  6. 6.CWE-362: Race Condition (opens in a new tab)
  7. 7.EIP-4895: Beacon chain push withdrawals as operations (opens in a new tab)
  8. 8.CWE-284: Improper Access Control (opens in a new tab)
  9. 9.OpenZeppelin Contracts: Utilities (Pausable) (opens in a new tab)
  10. 10.Solidity documentation: Events (opens in a new tab)

Quantix Technical Security Assessment QX-TSA-2026-009

Version 1.0, published 12 Jan 2026. A4 PDF generated from this assessment record.

Download Report

12

Report history

  1. 10 Nov 2025Review openedReviewed commit b8e4d2a07f1c in github.com/example-org/helion-core
  2. 5 Dec 2025Review closedThree reviewers over twenty working days, with a parallel specification and verification track
  3. After reviewRemediation reviewFixes checked at commit 41f0c7a9e2d5
  4. 12 Jan 2026Version 1.0 publishedQX-TSA-2026-009, A4 PDF generated from this record

Commission an assessment written to be verified.

Share the repository and the commit you plan to deploy. We reply with scoping questions and an estimate.