Skip to content

feat: base HyperLiquid activation detection on spot sends and creation fees#9594

Merged
dan437 merged 5 commits into
mainfrom
conf-1689-hyperliquid-activation-detection
Jul 23, 2026
Merged

feat: base HyperLiquid activation detection on spot sends and creation fees#9594
dan437 merged 5 commits into
mainfrom
conf-1689-hyperliquid-activation-detection

Conversation

@dan437

@dan437 dan437 commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Explanation

The hyperliquidActivationFee reserve added in #9238 decides whether to hold back the one-time HyperLiquid activation fee by probing userNonFundingLedgerUpdates. It currently treats any outbound ledger entry as proof of activation, including bridge withdraw entries, and assumes the account is activated whenever the probe fails.

That does not match how HyperLiquid charges the fee. Verified against the live API:

  • The fee is charged once per HyperCore account.
  • If an inbound spot transfer creates the account, the fee is charged on that transfer and recorded on the account's first ledger entry (fee: "1.0"). All later sends are then fee-free.
  • Accounts created another way (bridge deposit, perps trading) pay the fee on top of their first outbound spot send.
  • Bridge withdrawals use a separate fee lane and do not settle spot activation.
  • When an account's balance reaches zero it is purged together with its ledger, which also resets activation.

So an account whose only outbound history is bridge withdrawals is still unactivated for spot sends. The probe classified such accounts as activated, skipped the reserve, and their max withdrawals failed on the sendAsset step with Insufficient USDC balance for token transfer gas.

This PR reworks the detection:

  • Bridge withdrawals no longer count as activation.
  • An account counts as activated when its earliest ledger entry carries a fee of at least 1 (activation paid at creation), or when it has a prior outbound send/spotTransfer. A fee on a later inbound entry is ignored, because it belongs to the sender's own first-send activation.
  • Probe failures now reserve the fee instead of skipping it. Wrongly reserving leaves a small, recoverable balance on HyperLiquid; wrongly skipping fails the entire withdrawal.

It also fixes the feature flag lookup that gates the reserve. Most withdrawals are wrapped in an EIP-7702 batch, so the parent transaction type is batch and the overrides.perpsWithdraw.hyperliquidActivationFee config was never matched — the reserve was silently disabled for those accounts before the activation probe even ran. The override is now resolved through the first typed nested transaction when the parent is a batch, matching the existing type resolution in the relay submit and fiat strategies. In the meantime we solved this already in prod via a LD change.

Max withdrawals then leave no leftovers: activated accounts send 100% of their balance, and unactivated accounts reserve exactly the fee, which HyperLiquid consumes, so the account ends at zero.

References

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've communicated my changes to consumers by updating changelogs for packages I've changed
  • I've introduced breaking changes in this PR and have prepared draft pull requests for clients and consumer packages to resolve them

dan437 added 2 commits July 22, 2026 13:43
…n fees

The activation fee reserve for Pay withdrawals only applied to accounts
with no outbound ledger history at all. HyperLiquid charges the one-time
1 USDC activation fee on the first spot send unless it was already paid
by the inbound transfer that created the account. Bridge withdrawals use
a separate fee lane and do not settle it, so accounts whose only
outbound history was bridge withdrawals were wrongly classified as
activated and their max withdrawals failed with "Insufficient USDC
balance for token transfer gas".

- Stop treating bridge withdrawals as activation
- Treat a creation entry carrying a fee >= 1 as paid activation
- Reserve the fee when the activation check fails, instead of skipping
@dan437
dan437 marked this pull request as ready for review July 22, 2026 11:54
@dan437
dan437 requested review from a team as code owners July 22, 2026 11:54
@dan437
dan437 temporarily deployed to default-branch July 22, 2026 11:54 — with GitHub Actions Inactive
…rawals

EIP-7702 wrapped withdrawals have a top-level type of batch, so the
perpsWithdraw feature flag override was never matched and the activation
fee was silently disabled for most accounts.
Resolve CHANGELOG conflict by keeping both main's dependency bumps and
this PR's HyperLiquid activation fee fix entries.
@dan437
dan437 enabled auto-merge July 23, 2026 12:05
@dan437
dan437 added this pull request to the merge queue Jul 23, 2026
Merged via the queue into main with commit 2434e61 Jul 23, 2026
427 checks passed
@dan437
dan437 deleted the conf-1689-hyperliquid-activation-detection branch July 23, 2026 13:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants