Over the past few months building execution loops for autonomous trading agents across EVM and Solana, our engineering team ran into an architectural bottleneck: the "raw data supermarket" anti-pattern in Web3 security APIs.
When an autonomous LLM agent decides to execute an on-chain action (a swap, liquidity provision, or smart contract interaction), existing security tooling dumps 35+ unopinionated bytecode flags over HTTP:
is_honeypot: falsehas_blacklist: truehidden_owner_slot: 0x0...sell_tax: 0.15can_take_back_ownership: false
...and expects the LLM prompt to reason through what combination constitutes a critical rug pull.
The Flaws of Prompt-Level Bytecode Reasoning
Running this in high-frequency agent loops exposes two fatal problems:
- Latency and Token Overhead: Injecting a 2KB JSON blob of raw security telemetry into every trade evaluation burns context tokens and spikes reasoning latency by 400ms–1,200ms.
- Hallucination Under Ambiguity: LLMs are probabilistic engines. Under edge cases (e.g., dynamic tax hooks or multi-sig proxies), small variations in system prompts cause models to misjudge dangerous trapdoors.
First Principles: "The Verdict is the Product"
For autonomous execution pipelines, agents don't need raw telemetry; they need a deterministic go/no-go boundary.
We designed GuardDog (https://guarddog.top) around a single principle: evaluate the bytecode deterministically off-chain, and return an actionable verdict within 23ms (P95 server-side).
Verdict Specification:
- PASS: Clean contract, mainstream liquidity verification, zero trapdoor bytecode.
- WARN: High tax, unrenounced ownership, or unverified proxy logic (requires downstream agent risk threshold logic).
- BITE: Verified honeypot, transfer blacklists, or malicious drain logic. Immediate execution abort.
Integrating with Rust Agents (Rig Framework)
Following the community interest check on Rig issue #2908, we submitted the integration PR to awesome-rig (PR #24) and open-sourced the Rust client guarddog-rs.
Here is the entire 90-line implementation using standard reqwest + serde:
use serde::Deserialize;
#[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "UPPERCASE")]
pub enum Verdict {
Pass,
Warn,
#[serde(alias = "BLOCK")]
Bite, // the API returns BLOCK; BITE is the brand name
}
#[derive(Debug, Deserialize)]
pub struct SafetyReport {
pub verdict: Verdict,
pub risk_score: u32,
pub covered: bool,
pub reasons: Vec<String>,
pub data_limited: bool,
}
pub struct GuardDog {
client: reqwest::Client,
base_url: String,
}
impl GuardDog {
pub fn new() -> Self {
Self {
client: reqwest::Client::new(),
base_url: "https://api.guarddog.top/v1".to_string(),
}
}
pub async fn check(&self, chain: &str, contract: &str) -> Result<SafetyReport, reqwest::Error> {
// NOTE: the param name is `target`, not `address`
let url = format!("{}/check?chain={}&target={}", self.base_url, chain, contract);
self.client.get(&url).send().await?.json::<SafetyReport>().await
}
}
Usage in an Agent Loop:
let guard = GuardDog::new();
let report = guard.check("solana", "TokenContractAddressHere").await?;
if report.verdict == Verdict::Bite {
println!("Malicious contract detected: {:?}", report.reasons);
return Ok(ExecutionResult::Aborted);
}
Reproducible Testing: Open Benchmarks Over Marketing
To ground our detection claims, we open-sourced the Agent Honeypot Benchmark (AHB-1000) on GitHub:
- Repository: https://github.com/guarddog-top/agent-honeypot-benchmark
- Dataset: 1,000 real-world malicious contracts collected from academic corpora and live DEX telemetry.
- Results: 100% dataset coverage (1,000/1,000 contracts evaluated, zero unhandled errors), 48.1% alert rate on active deceptive tokens, 0.0% false positives across top 100 mainstream liquidity pairs.
Developer Free Tier
We provide an anonymous, zero-signup free tier (50 checks/day per IP):
- Direct endpoint:
https://api.guarddog.top/v1/check?chain=solana&target=<CONTRACT> - LLM Machine-readable spec:
https://guarddog.top/llms.txt - npm package: guarddog-mcp —
npx guarddog-mcpruns it locally in seconds.
Let's Discuss
For developers building autonomous trading agents and MCP workflows: how are you currently handling contract risk boundaries? Do you offload deterministic checks to specialized APIs, or do you let your prompt reason over raw data?
Top comments (0)