Threat model
What each part of the Zunder stack can and cannot do, and what happens when the bot, the relay, the website or a key is compromised, or a request is replayed.
This page says plainly what Guard protects against and what it does not. It covers Guard as planned for 1.0; where a protection exists in code today, the page says so.
The parts, and what each can do
Section titled “The parts, and what each can do”| Part | Runs on | Holds | Can | Cannot |
|---|---|---|---|---|
| Your bot or agent | your machine | a Guard client key | send orders to Guard | reach Hyperliquid with that key; exceed your limits |
| Guard (planned) | your machine | the API wallet key, the journal | sign and send orders within your limits; close positions | withdraw or transfer funds (an API wallet cannot); approve keys or builder fees |
| API wallet key | inside Guard | — | trade your account | withdraw, transfer, approve |
| Your main wallet | your wallet app | your funds’ key | everything | — Guard never asks for it |
| Relay (planned) | our server | nothing | forward, delay or drop requests | sign, place orders, read keys |
| zunderlabs.com | your browser | nothing of yours | read public Hyperliquid data; run the engine in your tab | connect a wallet, sign, see a key |
| Hyperliquid | the venue | your funds | everything a venue can | — out of scope here |
Threats
Section titled “Threats”1. The bot is compromised
Section titled “1. The bot is compromised”A bug, a malicious plug-in or a prompt injection makes your bot or agent send orders you did not want.
- Guard limits the damage to what your rules allow: each trade at most 2% at its stop, all stops together 6%, 5x exposure, the daily loss stop and the drawdown halt (defaults). It never has the API wallet key, so it cannot go around Guard.
- What remains: losses within the limits, every day until the drawdown halt. A bot can also buy an illiquid market at a bad price, from an accomplice on the other side, within its size limit. The market allowlist is the defence: allow only markets you trade. Your limits are the ceiling of what a compromised bot costs you.
- Exits pass. A compromised bot can close your positions at a bad moment. Guard does not block exits, by design.
2. The relay is compromised (planned component)
Section titled “2. The relay is compromised (planned component)”- Bot requests carry a client-key signature and a nonce. A compromised relay can delay or drop them. It cannot forge, replay, or push them past your limits (
docs/decisions.md, 6 Oct 2026). - TradingView alerts cannot be signed by TradingView. They carry a secret in their text, which the relay sees. A compromised relay could send its own alerts, which still pass all your rules. Open design point: how to bind alerts so that a relay cannot create them.
- What remains: missed alerts, delayed orders. Do not run a bot whose safety depends on the relay being up.
3. The website is compromised
Section titled “3. The website is compromised”zunderlabs.com is static. It holds no key, connects no wallet and signs nothing; Backtest, Watch and Live market read public data only.
- A compromised site could show false results, or a page that asks for a key. We never ask for a key, a seed phrase or a signature on the website. A page that does is not ours.
- It could serve a tampered download link. That is why releases are signed and their provenance is published: verify a release before you run it.
- A planned browser Guard (behind the relay) would hold an API wallet key in your tab. A compromised site could steal it. That is the reason the browser Guard is for trials, and bots running around the clock use the local Guard.
4. Key theft
Section titled “4. Key theft”- API wallet key stolen (from your machine or server): the thief can trade your account like a compromised bot, but without your limits, because they would not go through your Guard. They cannot withdraw. Remove the API wallet in the Hyperliquid app at once (API wallets). Keep only what you are willing to lose on that account.
- Client key stolen: the thief can send orders through your Guard, within your limits. Revoke the client key in Guard. Hyperliquid never knew it.
- Main wallet key stolen: out of Guard’s reach. Guard never asks for it.
Zunder’s own runner reads its key from standard input only, wipes the buffer after parsing, refuses a terminal, disables core dumps, and never prints, logs or writes the key (docs/testnet.md, “The key”). Guard is planned to keep the same discipline; how it stores the key between restarts is not decided.
5. Replay
Section titled “5. Replay”Someone records a valid request and sends it again.
- To Guard: every client request carries a nonce; Guard refuses a nonce it has seen or one that is too old (planned).
- To Hyperliquid: Guard signs every order with a fresh nonce. Hyperliquid’s own nonce rules apply.
- Across networks: a testnet signature is rejected on mainnet and the reverse (phantom agent source
"b"/"a", pinned against the official Python SDK’s vectors incrates/zunder-exec/src/hyperliquid/signing.rs). - Late arrival: Zunder’s entries carry an expiry (10 s, at most 30 s) so a request held up in the network cannot land long after it was meant (
docs/testnet.md). Guard is planned to keep this.
6. The journal is tampered with
Section titled “6. The journal is tampered with”The journal is checksum-chained: a changed, removed or reordered line is detected and trading stops. An older complete copy put in its place cannot be detected from the file (The journal).
Out of scope
Section titled “Out of scope”- Hyperliquid itself: its matching, liquidations, outages, bridge or validators.
- Your operating system and anything with root on your machine. Root can read any key and edit any file.
- Market risk within your limits. Guard enforces limits; it does not make trades good.
- Gaps through a stop. A stop can fill far beyond its trigger.
Reporting
Section titled “Reporting”Found a way around any of this? Report it.
This page as plain Markdown, for people and LLMs: /docs/security/threat-model.md