Skip to content
Join the waitlistWaitlist

Veto and reason codes

Every code Guard, the risk engine and the browser tools use to say why an entry was refused or resized.

A refusal always carries a code (stable, for programs) and a reason (a sentence, for people). Codes are snake_case and never change meaning; new ones may be added.

Codes marked run a tiny example through the real risk engine in your browser.

Veto in crates/zunder-risk/src/engine.rs. The codes are the variant names in snake_case, as the WebAssembly build serialises them (VetoCode in crates/zunder-risk-wasm/src/api.rs).

CodeRuleReason (the engine’s own)Example
halted_for_day(h)trading is halted for the daydown 6% since 00:00 UTC
stopped(i)trading is stopped until a manual review25% below the peak
stop_on_wrong_side(g)the stop is not on the losing side of the entry pricebuy at 100, stop at 101
open_risk_exhausted(e)the open-risk budget is used upstops already risk 6%
leverage_exhausted(c)the leverage cap is reachedpositions already worth 5× equity
below_minimum(g)the sized quantity is below the venue minimumthe allowed size is worth less than the minimum order
unprotected_position(e)an open position has no protective stop, or its price is at or through itan ETH position without a stop blocks a BTC entry
invalid_request(g)the sizing request contains a negative or non-positive amounta price of 0
overflow(g)the numbers are too large or too small to size safelyabsurd inputs

Policy: in the website’s judge (being built)

Section titled “Policy: in the website’s judge (being built)”

crates/zunder-risk-wasm/src/judge.rs. Planned to be the same in Guard’s policy.

CodeRuleExample reason
coin_not_allowed(a)HYPE is not on the market allowlist
no_protective_stop(b)no stop order protects the ETH position
unbounded_risk(b)neither a stop nor a liquidation price bounds the loss
liquidation_too_close(d)liquidation is 7% from the price; the minimum is 10%
position_cap_reached(f)a position may be worth at most 200% of account value
equity_not_positive(g)the account has no positive equity

Resizes carry the rule that bound the size instead of a code: max_leverage, max_open_risk, max_position_size or max_loss_per_trade, with a reason such as “a stop-out may lose at most 2% of equity”.

crates/zunder-risk-wasm/src/account.rs. Not refusals: warnings about the account as a whole.

CodeMeaning
halted_for_daythe daily loss stop is reached
stoppedthe drawdown halt is reached
position_without_stopa position has no protective stop
open_risk_over_capopen risk is over your cap
leverage_over_capleverage is over your cap
CodeMeaning
killedthe kill switch is pulled; nothing opens until a person releases it
client_not_allowedthe request was signed by a key that is not a client of this Guard
nonce_reusedthe nonce was already used, or is too old
action_not_allowedan action Guard never forwards: withdrawals, transfers, key or builder approvals
stop_loosening_ignorednot a refusal: the stop stayed where it was (Stops only tighten)
not_readyGuard is reconciling, or waiting out its start-up wait
margin_not_setisolated margin could not be confirmed before the entry
no_safe_leverageno leverage of 1x or more keeps liquidation beyond the stop

The last two follow SessionError::MarginNotSet and SessionError::NoSafeLeverage in Zunder’s session, which exist today.

This page as plain Markdown, for people and LLMs: /docs/reference/veto-codes.md