Back to Hub
CREATED BY CHAINLINK LABS

AI Smart Contract Audit Firewall

Automatically analyze and screen smart contract interactions before execution to detect and block malicious transactions, while preserving the confidentiality of chain scanner and LLM reasoning API credentials.

What this template does

This CRE workflow implements a confidential pre-execution security firewall for smart contract interactions. Before a proposed transaction is allowed to proceed, the workflow fetches token and protocol contract artifacts from a blockchain scanner, submits them to two independent AI reasoning models, and enforces a security verdict. All scanner and LLM credentials remain protected inside confidential execution throughout the process.

Data flow:

  1. Receive a candidate transaction containing token and protocol contract addresses.
  2. Validate scanner credential scopes (verification:read, contracts:read) before trusting fetched data.
  3. Fetch source and ABI artifacts for both contracts through the scanner.
  4. Verify that both contracts are on-chain verified. Unverified contracts result in an immediate denial.
  5. Submit each contract to independent primary and secondary reasoning models in sequence, using primary analysis results as prior context for the secondary model.
  6. Merge risk flags from both models using OR logic and determine the final verdict.
  7. Post audit and firewall action records to the database log.
  8. Optionally deliver the signed verdict on-chain to a consumer contract.

Risk Flags and Verdict Logic

Risk flags

Both models independently classify contract behavior into four structured risk signals:

FlagDescription
obfuscatedTaxHidden fee or tax mechanism detected in the contract
privilegeEscalationOwner or operator can drain funds or alter critical parameters
externalCallRiskCalls to external contracts that can alter contract behavior
logicBombDormant code that activates under a specific condition

Risk flags from both models are merged with OR logic: if either model sets a flag, it is included in the final risk assessment.

Verdict logic

VerdictCondition
DENYEither contract is unverified, or any merged risk flag is true
MANUAL_REVIEWEither model recommends review, either model has confidence below 0.7, or the two models disagree on their recommendation
ALLOWNo risk flags detected, both models recommend allow, and both models have confidence ≄ 0.7

Prerequisites

  • Bun runtime
  • CRE CLI (cre)
  • A blockchain scanner account with an API key that has verification:read and contracts:read scopes
  • API keys for two LLM reasoning endpoints (primary and secondary)

Configuration

The workflow ships with two config files:

  • ai-audit-firewall-ts/config.staging.json (TypeScript) and ai-audit-firewall-go/config.staging.json (Go): targets mock server endpoints and Ethereum Sepolia testnet
  • ai-audit-firewall-ts/config.production.json (TypeScript) and ai-audit-firewall-go/config.production.json (Go): same structure with empty URLs for you to populate

Key fields:

FieldDescription
scheduleCron expression for execution frequency. Default: 0 */5 * * * * (every 5 minutes)
scanner_urlScanner API endpoint for contract metadata and verification
primary_llm_urlPrimary reasoning model endpoint
secondary_llm_urlSecondary reasoning model endpoint
secrets_ids.scanner_api_key_idSecret ID for scanner credentials
secrets_ids.primary_llm_api_key_idSecret ID for primary model credentials
secrets_ids.secondary_llm_api_key_idSecret ID for secondary model credentials
mock_base_urlBase URL used for audit log and firewall action posts. Required even in production.
evms[].chain_selector_nameTarget chain for on-chain verdict delivery. Remove the evms array to disable.
evms[].consumer_addressDeployed AuditFirewallConsumer contract address
evms[].gas_limitGas limit for on-chain verdict writes

Secrets

Copy .env.example to .env and populate all values before running locally.

Environment variableSecret IDPurpose
MOCK_SCANNER_API_KEYscanner_api_keyAuthenticates requests to the blockchain scanner
MOCK_PRIMARY_LLM_API_KEYprimary_llm_api_keyAuthenticates requests to the primary reasoning model
MOCK_SECONDARY_LLM_API_KEYsecondary_llm_api_keyAuthenticates requests to the secondary reasoning model
CRE_ETH_PRIVATE_KEY(framework-level)Signs transactions for on-chain verdict delivery. Optional for local simulation.

Secret IDs are referenced in secrets.yaml and mapped to their corresponding secret IDs in config.staging.json under secrets_ids. For production, register each secret with the CRE secrets manager using those IDs.

Quick start

TypeScript

Run all commands from the ai-audit-firewall directory (the project root).

  1. Install dependencies

    cd ai-audit-firewall-ts && bun install && cd ..
    
  2. Create environment file

    cp .env.example .env
    
  3. Start mock server

    cd ai-audit-firewall-ts && bun run mock:server
    
  4. In another terminal, run checks and simulate

    cd ai-audit-firewall-ts
    bun run typecheck
    bun run test
    cd .. && cre workflow simulate ./ai-audit-firewall-ts --project-root ./ --target=staging-settings --env ./.env
    

Go

Run all commands from the ai-audit-firewall directory (the project root).

  1. Create environment file

    cp .env.example .env
    
  2. Start the mock server from the TypeScript directory (requires Node or Bun)

    cd ai-audit-firewall-ts && bun run mock:server
    
  3. In another terminal, run checks and simulate

    cd ai-audit-firewall-go
    go vet ./...
    go test ./...
    cd .. && cre workflow simulate ./ai-audit-firewall-go --project-root ./ --target=staging-settings --env ./.env
    

Production checklist

  • Populate config.production.json with real scanner_url, primary_llm_url, secondary_llm_url, and mock_base_url.
  • Register scanner_api_key, primary_llm_api_key, and secondary_llm_api_key in the CRE secrets manager.
  • Confirm the scanner API key has both verification:read and contracts:read scopes. The workflow validates this at runtime and fails fast if scopes are missing.
  • Set CRE_ETH_PRIVATE_KEY if on-chain verdict delivery is enabled.
  • Deploy AuditFirewallConsumer.sol and set its address in config.production.json under evms[].consumer_address.
  • Run bun run typecheck && bun run test (TypeScript) or go vet ./... && go test ./... (Go) before registering.
  • Run cre workflow simulate against production endpoints to validate end-to-end behavior before going live.
  • Register the workflow:
    • TypeScript: cre workflow register ./ai-audit-firewall-ts --project-root ./ --target=production-settings
    • Go: cre workflow register ./ai-audit-firewall-go --project-root ./ --target=production-settings

Troubleshooting

Scanner credential validation fails

The workflow validates scopes before making any scanner calls. If you see a scope-related error, confirm your scanner API key has verification:read and contracts:read permissions. The error message includes the detected scopes for diagnosis.

Verdict is DENY for an unverified contract

Unverified contracts are denied without running LLM analysis. If you are testing with a contract that is not on-chain verified, use the mock server (which returns mock verification status) or switch to a verified contract address.

LLM response cannot be parsed

If you see invalid json response or a parsing error, the reasoning endpoint returned a malformed body. Confirm that the LLM URL and API key are correct and that the model returns a JSON object with recommendation, confidence, and riskFlags fields.

On-chain write fails

Confirm that CRE_ETH_PRIVATE_KEY is set and the consumer contract is deployed on the target chain. The workflow logs audit-firewall-onchain tx_hash=... on success. A failed transaction throws an error with the transaction status.

Capability limit errors

The workflow enforces a cap of 10 total capability calls per invocation (8 HTTP, 1 Report/consensus, and optionally 1 EVM write when on-chain delivery is enabled). If you extend the workflow with additional HTTP calls, update the pre-hook capability limits accordingly.

Optional on-chain delivery

After each audit, the workflow can write a signed verdict to an on-chain consumer contract. On-chain delivery is controlled by the evms array in the config. Remove the array or leave it empty to run the workflow without any on-chain writes.

Verdict encoding

Verdicts are ABI-encoded as (uint8 verdictCode, uint8 riskMask, uint64 chainSelector):

FieldValueMeaning
verdictCode1ALLOW
verdictCode2DENY
verdictCode3MANUAL_REVIEW

Risk flags are packed into riskMask as a single bitmask byte: bit 0 = obfuscatedTax, bit 1 = privilegeEscalation, bit 2 = externalCallRisk, bit 3 = logicBomb.

Consumer contract

The included AuditFirewallConsumer.sol extends ReceiverTemplate and exposes the latest verdict, risk mask, and chain selector as public state variables. It emits a VerdictReceived event on each report. Deploy this contract and set its address in config.production.json under evms[].consumer_address.

Deployment target

The staging config targets Ethereum Sepolia (ethereum-testnet-sepolia). For mainnet delivery, update chain_selector_name to ethereum-mainnet and redeploy the consumer contract to that network.

Get the latest Chainlink content straight to your inbox.