AURA

Policy Engine

All 27 ViolationCodes, evaluation order, public precheck vs full evaluation, and PolicyConfig defaults from the actual aura-policy source.

aura-policy is a pure-Rust crate with no Anchor dependency. It is consumed by aura-core on-chain, by sdk-rs for off-chain pre-validation, and by the devnet smoke binaries. All rule logic, violation codes, and FHE graph specs live here — never duplicated in aura-core or the SDKs.

Entry Points

FunctionUsed byWhat it skips
evaluate_transactionPublic proposals (propose_transaction)Nothing — runs all rules
evaluate_public_precheckConfidential proposals (before FHE CPI)per_tx_limit, daily_limit — deferred to Encrypt
evaluate_transaction_simpleTests and off-chain toolingConvenience wrapper
evaluate_batchpropose_batch instructionEvaluates a slice, threads state forward
evaluate_policy_without_spend_mutationsimulate_policy instructionRuns full rules but does not commit state

Evaluation Order (evaluate_transaction)

Rules short-circuit on the first failure. No subsequent rules are evaluated after a violation.

Public Precheck vs Full Evaluation

For confidential proposals, evaluate_public_precheck runs the same rules except steps 3 (per_tx_limit) and 4 (daily_limit). Those are deferred to the FHE circuit. If the precheck passes, a note is added to the trace: "encrypted per-transaction and daily-limit checks deferred to Encrypt".

All 27 ViolationCodes

From programs/aura-policy/src/violations/mod.rs:

CodeVariantTriggered when
noneNoneTransaction approved
per_transaction_limitPerTransactionLimitamount_usd > per_tx_limit_usd
daily_limitDailyLimitspent_today + amount > effective_daily_limit
bitcoin_manual_reviewBitcoinManualReviewBitcoin tx above bitcoin_manual_review_threshold_usd
time_window_limitTimeWindowLimitHourly spend would exceed active hourly limit
velocity_limitVelocityLimitRecent-amounts window sum would exceed velocity_limit_usd
protocol_not_allowedProtocolNotAllowedProtocol ID bit not set in allowed_protocol_bitmap
slippage_exceededSlippageExceededComputed slippage > max_slippage_bps
quote_staleQuoteStalequote_age_secs > max_quote_age_secs
counterparty_riskCounterpartyRiskRisk score > max_counterparty_risk_score
shared_pool_limitSharedPoolLimitSwarm pool projected spend > shared_pool_limit_usd
weekly_limitWeeklyLimit7-day total would exceed weekly_limit_usd
monthly_limitMonthlyLimit30-day total would exceed monthly_limit_usd
recipient_daily_limitRecipientDailyLimitPer-address daily cap exceeded
recipient_per_transaction_limitRecipientPerTransactionLimitPer-address per-tx cap exceeded
anomaly_detectedAnomalyDetectedZ-score outlier with action = Deny
cooldown_not_elapsedCooldownNotElapsedCooldown rule blocked a large transaction
budget_envelope_daily_limitBudgetEnvelopeDailyLimitScoped envelope daily cap exceeded
budget_envelope_weekly_limitBudgetEnvelopeWeeklyLimitScoped envelope weekly cap exceeded
approval_ladder_deniedApprovalLadderDeniedApproval ladder returned ApprovalLevel::Deny
execution_scope_pausedExecutionScopePausedTransaction matches an active ScopedPauseEntry
external_dependency_staleExternalDependencyStaleRequired liveness record is stale
policy_attestation_missingPolicyAttestationMissingAttestation missing or stale
empty_batchEmptyBatchBatch proposal contained no items
batch_too_largeBatchTooLargeBatch exceeded maximum item count
exposure_group_limit_exceededExposureGroupLimitExceededCross-treasury exposure group cap exceeded
pending_execution_timelock_activePendingExecutionTimelockActiveExecution timelock still active

PolicyConfig Defaults

From programs/aura-policy/src/config/limits.rsPolicyConfig::default():

FieldDefaultDescription
daily_limit_usd10_000USD cents — 24h rolling window
per_tx_limit_usd1_000USD cents — single transaction cap
daytime_hourly_limit_usd2_500USD cents — 06:00–22:00 UTC
nighttime_hourly_limit_usd500USD cents — 22:00–06:00 UTC
velocity_limit_usd5_000USD cents — recent-amounts window
allowed_protocol_bitmap0b1_1111 (31)All 5 protocol bits set
max_slippage_bps1001%
max_quote_age_secsSome(300)5 minutes
max_counterparty_risk_scoreSome(70)0–100 scale
bitcoin_manual_review_threshold_usd5_000USD cents = $50
shared_pool_limit_usdNoneDisabled
weekly_limit_usdNoneDisabled
monthly_limit_usdNoneDisabled
recipient_limits[]No per-address caps
cooldown_configNoneDisabled
anomaly_configNoneDisabled
budget_envelopes[]No scoped envelopes
approval_ladderNoneDisabled
scoped_pauseemptyNo pauses
liveness_configall falseNo freshness requirements

Reputation Scaling

effective_daily_limit_usd is computed as:

effective = daily_limit_usd × multiplier_bps(reputation_score) / 10_000

Default ReputationPolicy:

ThresholdMultiplier
score ≥ high_score_threshold (80)high_multiplier_bps / 10_000 = 1.5×
score ≥ medium_score_threshold (50)1.0× (baseline)
score < 50low_multiplier_bps / 10_000 = 0.7×

If no reputation score is provided (None), the base daily_limit_usd is used unchanged.

Time Windows

active_hourly_limit returns daytime_hourly_limit_usd for hours 6–21 UTC and nighttime_hourly_limit_usd for hours 22–5 UTC. The hourly counter (hourly_spent_usd) resets when the current hour changes.

Transaction Types

From programs/aura-policy/src/types/transaction.rs:

IDVariantDisplay
0Transfertransfer
1DeFiSwapdefi_swap
2LendingDepositlending_deposit
3NFTPurchasenft_purchase
4ContractInteractioncontract_interaction

Regulatory Flags

compute_regulatory_flags returns a u8 bitmask attached to every PolicyDecision:

BitConstantMeaning
0b0000_0001REG_FLAG_CTR_THRESHOLDAmount exceeds CTR reporting threshold
0b0000_0010REG_FLAG_CROSS_BORDERCross-chain transaction
0b0000_0100REG_FLAG_HIGH_RISK_COUNTERPARTYRisk score above 80
0b0000_1000REG_FLAG_REQUIRES_KYCTransaction type requires KYC

Anomaly Detection

When anomaly_config.enabled = true and state.recent_amounts.len() >= min_sample_size, the engine computes a z-score over the recent amounts window:

z_score_bps = (amount - mean) / std_dev × 10_000

If z_score_bps > z_score_threshold_bps, the action is applied:

AnomalyActionEffect
DenyReturns ViolationCode::AnomalyDetected
FlagForReviewSets risk_score = max(risk_score, 85), adds risk factor, continues
RequireGuardianCosignRequires guardian approval before execution

On this page