Decisions and failures
The evaluator's current decision values, failure codes, result fields, and transaction boundary.
MandateEvaluator.evaluate returns a structured result. The decision describes what the authority layer permits next. It does not describe whether a transaction was mined or whether a downstream call succeeded; see Transaction lifecycle for that distinction.
Decision values
| Value | Meaning |
|---|---|
ALLOW | The plan satisfies the active Mandate, signature, action, amount, and Preflight checks, so VaultExecutor.execute may continue. |
ESCALATE | A configured amount or Preflight boundary was crossed and the relevant escalation flag is enabled, so the plan may be submitted to EscalationManager for owner approval. |
DENY | The plan is not authorised, or the relevant boundary was crossed without permission to escalate. The executor rejects it before moving capital. |
An ESCALATE result does not approve the plan. Submission stores the complete plan and signature, and the Vault owner must approve the stored digest before executeEscalated can proceed. The executor evaluates the stored plan again at execution time.
Result fields
struct EvaluationResult {
uint8 decision;
uint8 failureCode;
uint256 failedActionIndex;
uint256 nativeAmount;
uint256 nativeUsdValue;
uint256 nativeBalanceAfter;
uint256 nativeBalanceUsdValue;
}failedActionIndex is the zero-based action index for an action-specific validation failure. type(uint256).max means that no individual action is identified, which is the normal value for a successful result, rule-level failures, and plan-level failures. nativeAmount is the aggregate native outflow in raw base units. nativeUsdValue is the USD valuation of that outflow when a Chainlink feed is available. nativeBalanceAfter is the projected Vault native balance after execution. nativeBalanceUsdValue is the USD valuation of the projected remaining balance.
Plan and authority failures
These failures happen before amount rules are applied and always return DENY:
| Failure code | Meaning |
|---|---|
MANDATE_NOT_FOUND | mandateId is zero or outside the registry's current Mandate count. |
MANDATE_INACTIVE | The Mandate or one of its ancestors is revoked. |
MANDATE_NOT_YET_VALID | Current block timestamp is before the effective validAfter. |
MANDATE_EXPIRED | Current block timestamp is after the effective validUntil. |
MANDATE_PAUSED | The Mandate or one of its ancestors is paused. |
VAULT_PAUSED | The Vault referenced by the Mandate is paused. |
AGENT_MISMATCH | The plan agent differs from the agent stored on the Mandate. |
EXPIRED | deadline is non-zero and earlier than the current block timestamp. |
EMPTY_PLAN | The plan contains no actions. |
Signature and nonce failures
| Failure code | Meaning |
|---|---|
INVALID_SIGNATURE | The EIP-712 signature is malformed, does not recover to the Mandate agent, uses an invalid recovery value, or uses a high-s value. |
NONCE_USED | The nonce for this (Mandate, agent) pair was already consumed by a previous execution or cancelled. |
NONCE_RESERVED | The nonce is reserved for an escalation digest. A normal execution cannot use it. |
The evaluator binds the digest to the current chain and evaluator address, then requires the recovered signer to match the Mandate agent. NONE means that no failure was found; the evaluator returns it with ALLOW.
Action validity
These failures identify the first invalid action where applicable:
| Failure code | Meaning |
|---|---|
INVALID_ACTION | The action version is not the current version for its type, or its parameter bytes are empty. |
INVALID_ACTION_PARAMETERS | The current transfer parameter bytes are not exactly the 96-byte ABI encoding expected by TransferParameters. |
INVALID_RECIPIENT | The decoded transfer recipient is the zero address. |
INVALID_AMOUNT | The decoded transfer amount is zero. |
Amount bounds
These failures compare aggregate plan amounts with effective Mandate rules:
| Failure code | Meaning |
|---|---|
AMOUNT_OVERFLOW | Aggregate native amount would overflow uint256. |
NATIVE_AMOUNT_BELOW_MINIMUM | Aggregate native amount is below a configured non-zero minimum. The result becomes ESCALATE only when effective native escalation remains enabled. |
NATIVE_AMOUNT_ABOVE_MAXIMUM | Aggregate native amount exceeds a configured non-zero maximum. The result becomes ESCALATE only when effective native escalation remains enabled. |
NATIVE_USD_VALUE_BELOW_MINIMUM | Aggregate native-asset USD valuation is below a configured non-zero minimum. The result becomes ESCALATE only when effective native-USD escalation remains enabled. |
NATIVE_USD_VALUE_ABOVE_MAXIMUM | Aggregate native-asset USD valuation exceeds a configured non-zero maximum. The result becomes ESCALATE only when effective native-USD escalation remains enabled. |
Valuation
| Failure code | Meaning |
|---|---|
NATIVE_USD_VALUATION_UNAVAILABLE | A native-USD limit is enabled, a required Chainlink quote is unavailable, and the evaluator cannot complete valuation. |
Preflight
| Failure code | Meaning |
|---|---|
PREFLIGHT_NATIVE_BALANCE_BELOW_MINIMUM | The projected Vault native balance after aggregate native outflow is below the effective Preflight floor. The result becomes ESCALATE only when effective Preflight escalation remains enabled. |
PREFLIGHT_NATIVE_USD_BALANCE_BELOW_MINIMUM | The USD value of projected Vault native balance after execution is below the effective native-USD Preflight floor. The result becomes ESCALATE only when effective escalation remains enabled. |
SWAP failures
| Failure code | Meaning |
|---|---|
SWAP_UNSUPPORTED | No configured adapter exists for the requested SwapAdapterId. |
INVALID_SWAP_PARAMETERS | Decoded swap parameters fail validation (zero amounts, empty hops). |
INVALID_SWAP_ROUTE | The adapter's validateSwap call rejected the route (wrong factory, bad pool, token mismatch, fee issues). |
Native amount rules apply to the aggregate native outflow of both TRANSFER and SWAP actions. SWAP actions contribute their input amount to the native total when the input is native or wrapped native.
Transaction boundary
Evaluation is a read-only call and does not create a durable event. VaultExecutor.execute accepts only ALLOW; DENY and ESCALATE cause the executor call to revert. EscalationManager.submit accepts only ESCALATE, while approval and execution are separate transactions.
If a submitted executor transaction reverts, events emitted during that transaction do not persist. A reverted receipt proves that a transaction attempt failed, but it is not a persisted authorisation record. Persistent records come from committed events such as MandateRevoked, EscalationSubmitted, or ActionPlanExecuted.
See Transaction lifecycle for the contract path and Events for the durable event surface.
Last updated on