Grantline Docs
Reference

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

ValueMeaning
ALLOWThe plan satisfies the active Mandate, signature, action, amount, and Preflight checks, so VaultExecutor.execute may continue.
ESCALATEA 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.
DENYThe 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 codeMeaning
MANDATE_NOT_FOUNDmandateId is zero or outside the registry's current Mandate count.
MANDATE_INACTIVEThe Mandate or one of its ancestors is revoked.
MANDATE_NOT_YET_VALIDCurrent block timestamp is before the effective validAfter.
MANDATE_EXPIREDCurrent block timestamp is after the effective validUntil.
MANDATE_PAUSEDThe Mandate or one of its ancestors is paused.
VAULT_PAUSEDThe Vault referenced by the Mandate is paused.
AGENT_MISMATCHThe plan agent differs from the agent stored on the Mandate.
EXPIREDdeadline is non-zero and earlier than the current block timestamp.
EMPTY_PLANThe plan contains no actions.

Signature and nonce failures

Failure codeMeaning
INVALID_SIGNATUREThe EIP-712 signature is malformed, does not recover to the Mandate agent, uses an invalid recovery value, or uses a high-s value.
NONCE_USEDThe nonce for this (Mandate, agent) pair was already consumed by a previous execution or cancelled.
NONCE_RESERVEDThe 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 codeMeaning
INVALID_ACTIONThe action version is not the current version for its type, or its parameter bytes are empty.
INVALID_ACTION_PARAMETERSThe current transfer parameter bytes are not exactly the 96-byte ABI encoding expected by TransferParameters.
INVALID_RECIPIENTThe decoded transfer recipient is the zero address.
INVALID_AMOUNTThe decoded transfer amount is zero.

Amount bounds

These failures compare aggregate plan amounts with effective Mandate rules:

Failure codeMeaning
AMOUNT_OVERFLOWAggregate native amount would overflow uint256.
NATIVE_AMOUNT_BELOW_MINIMUMAggregate native amount is below a configured non-zero minimum. The result becomes ESCALATE only when effective native escalation remains enabled.
NATIVE_AMOUNT_ABOVE_MAXIMUMAggregate native amount exceeds a configured non-zero maximum. The result becomes ESCALATE only when effective native escalation remains enabled.
NATIVE_USD_VALUE_BELOW_MINIMUMAggregate 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_MAXIMUMAggregate native-asset USD valuation exceeds a configured non-zero maximum. The result becomes ESCALATE only when effective native-USD escalation remains enabled.

Valuation

Failure codeMeaning
NATIVE_USD_VALUATION_UNAVAILABLEA native-USD limit is enabled, a required Chainlink quote is unavailable, and the evaluator cannot complete valuation.

Preflight

Failure codeMeaning
PREFLIGHT_NATIVE_BALANCE_BELOW_MINIMUMThe 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_MINIMUMThe 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 codeMeaning
SWAP_UNSUPPORTEDNo configured adapter exists for the requested SwapAdapterId.
INVALID_SWAP_PARAMETERSDecoded swap parameters fail validation (zero amounts, empty hops).
INVALID_SWAP_ROUTEThe 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

On this page