Where Clause
The where clause lists preconditions that must hold before a route runs.
Each condition pairs with a throw that fires if the condition is false.
Syntax
withdraw(amount: U256)
where m_balance >= amount : throw InsufficientBalance(m_balance, amount)
=> [
~> msg::sender with { value: amount }
]
Prefer named errors (throw ErrorName(args)) so EVM codegen emits typed
custom errors. See Custom Errors.
Multiple conditions
Chain conditions with &&. Each has its own throw:
transfer(to: address, amount: U256)
where m_balances[msg::sender] >= amount : throw InsufficientBalance(m_balances[msg::sender], amount)
&& to != msg::sender : throw SelfTransfer()
&& m_status == Status::Active : throw Paused()
=> []
Conditions evaluate in order. On failure the transaction reverts immediately; no later actions or member transforms run.
Condition expressions
Any boolean expression is valid: comparisons, equality, macro calls
(@is_owner()), map lookups, and compounds:
where msg::value > 0 : throw ZeroValue()
where msg::sender == m_owner : throw Unauthorized()
where @is_owner() : throw Unauthorized()
where m_whitelist.exists(msg::sender) : throw NotWhitelisted()
where (m_deadline == 0 || sys::now < m_deadline) : throw Expired()
Where with from
Sender checks run before where:
process(data: bytes)
from Oracle(m_oracle_id) : throw BadSender()
where m_status == Status::Active : throw Paused()
&& data.len() > 0 : throw EmptyData()
=> []
Per-phase where
On phased routes, a later phase may attach its
own guard that can read var captures from earlier phases:
withdraw(who: address) => [
fetch: [
var bal = balanceOf(who) ~> m_token;
]
act where bal > 0 : throw EmptyBalance(): [
// …
]
]
Route-level where runs before any phase and must not reference var
bindings (V27). Per-phase where may only see vars from strictly
earlier phases (V28). Prefer unphased routes unless you need a
synchronous capture or interleaved effects.
Init routes
init setup(owner: address, limit: U256)
where limit > 0 : throw BadLimit()
=> []