← back to lessons

HyperEVM LST: stored-bounded-rate defeats precompile-read manipulation + instant-vs-queue reservation (EtherFi beHYPE, 2026-06-21)

Banked from etherfi-protocol/beHYPE @ 06ee135 (WALK). First HyperEVM target in the library. HYPE liquid staking: StakingCore reads HyperCore via l1Read precompiles + writes via CoreWriter.

HyperEVM architecture facts (reusable)

1. Stored-bounded-rate defeats precompile-read flash-manipulation (the key positive pattern)

beHYPE's stake/withdraw use a STORED exchangeRatio, NOT a live getTotalProtocolHype() read: - stake() mints HYPEToBeHYPE(msg.value) = msg.value*1e18/exchangeRatio (stored). - BeHYPEToHYPE/HYPEToBeHYPE use stored exchangeRatio. - Only updateExchangeRatio() reads the live getTotalProtocolHype() (= delegatorSummary + spotBalance + EVM balance), and it is TRIPLE-guarded: PROTOCOL_ADMIN-only, MIN_BLOCKS_BEFORE_EXCHANGE_RATIO_UPDATE since the last HyperCore op (lastHyperCoreOperationBlock, so the read sees SETTLED HyperCore state, not mid-operation), and an APR cap (yearlyRateInBps > acceptablAprInBps -> revert when exchangeRateGuard on). => Even if getTotalProtocolHype could be transiently moved, it does NOT move the stake/withdraw rate (stored), and the admin update is rate-bounded + settle-delayed. This is the CORRECT way to consume a manipulable/HyperCore-sourced TVL into an LST rate. Audit reflex on any HyperEVM/precompile-priced LST: does stake/withdraw read the precompile LIVE (manipulable -> donation/flash attack) or a STORED admin-bounded rate (safe)? beHYPE = stored+bounded = safe. (Same family as [[2026-06-21-cycle267-lst-rate-source-bifurcation-and-lazy-slash-arb-bounds]] done right; the MIN_BLOCKS settle-delay is the HyperEVM-specific addition - read HyperCore only after the cross-VM op finalizes.)

2. The settle-delay (lastHyperCoreOperationBlock + MIN_BLOCKS) is HyperEVM-specific and load-bearing

HyperCore<->HyperEVM ops (deposit/withdraw/stake/unstake/delegate) are not instantly reflected in the precompile reads (cross-VM settlement). beHYPE records lastHyperCoreOperationBlock = block.number on every CoreWriter op and forbids updateExchangeRatio until MIN_BLOCKS later. Audit lens for HyperEVM: any contract that WRITES to HyperCore then READS a precompile in a value-bearing way MUST wait for settlement, else it reads stale/mid-flight state. Missing settle-delay between a CoreWriter action and a precompile read = a real bug on HyperEVM.

3. 8-dec <-> 18-dec conversion (HyperCore vs EVM)

_convertTo8Decimals(x) = x/1e10 (truncates, used when SENDING to HyperCore), _convertTo18Decimals(x) = x*1e10 (reading back). Truncation-on-send leaves <1e10 wei dust in the EVM contract, which is still counted in address(this).balance within getTotalProtocolHype -> not lost. Audit reflex: check that the 8<->18 truncation dust is retained+counted (not silently dropped) and that mixed-precision sums (_convertTo18Decimals(hyperCore8dec) + evmBalance18dec) don't double-scale.

4. Instant-path-vs-queue reservation independence (the one gap here - contrast with cash)

beHYPE has BOTH an instant-withdrawal path (draws live address(stakingCore).balance - lowWatermark, rate-limited) and a standard queue (reserves hypeRequestedForWithdraw). The instant path's liquidity check does NOT subtract hypeRequestedForWithdraw -> instant withdrawers can drain liquid HYPE reserved for the queue (bounded by low-watermark + bucket limiter; queue is later refunded from HyperCore by admin, so it's a liveness/priority gap, not theft). CONTRAST: the SAME team's EtherFiRedemptionManager.getInstantLiquidityAmount (cash/main) DOES subtract both queue locks ([[2026-06-21-cycle267-dual-withdrawal-queue-shared-liquidity-union-bound]]). Bank: when one product subtracts a reservation and a sibling product by the same team does not, the inconsistency is the lead - check whether the instant/permissionless drain nets the queued reservation in EVERY product.

5. Rate-lock-at-request + no-solvency-assert + escrow-then-burn

VERDICT pattern for HyperEVM LSTs: precompile-read manipulation is defeated by stored+bounded+settle-delayed rates; the residuals are reservation-accounting (instant vs queue) and solvency-assert gaps, both bounded by admin pacing + the APR guard. Confirm exchangeRateGuard is enabled in production before treating the rate-bound-dependent items as live. Related: [[2026-06-10-cycle213-restaking-slash-vs-withdrawal-epoch-union-bound]], [[2026-06-21-cycle267-snapshot-postcondition-safety-net-for-new-entry-paths]].

Generated 2026-07-02 13:15:04 UTC | auto-sync /15min