> ## Documentation Index
> Fetch the complete documentation index at: https://docs.webacy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Trading Bot Risk Engine

> Add sub-200ms token risk screening to your trading bot or sniper to filter honeypots, hidden taxes, sniper clusters, and low-liquidity traps before buying.

Your bot finds a 10x opportunity—a new token trending on social with an early chart that looks perfect. You buy in automatically. When you try to take profit, nothing happens—there's a 95% sell tax. The token is a honeypot designed to trap bots. This guide shows you how to filter the noise and protect your capital.

## Why Bots Need Risk Screening

<CardGroup cols={3}>
  <Card title="Speed + Safety" icon="bolt">
    Sub-second screening that doesn't slow down execution
  </Card>

  <Card title="Honeypot Detection" icon="jar-wheat">
    Catch traps before capital gets locked
  </Card>

  <Card title="Sniper Detection" icon="crosshairs">
    Know when you're competing against coordinated actors
  </Card>
</CardGroup>

**Why trading bot developers choose Webacy:**

* **Trading Lite API** — Sub-200ms token screening optimized for bots
* **Honeypot detection** — Don't buy what you can't sell
* **Hidden tax detection** — Expose the real cost before buying
* **Holder analysis** — Detect sniper clusters and bundler activity
* **Liquidity analysis** — Verify there's enough depth to exit
* **Multi-chain support** — Solana, Base, ETH, and more

***

## Prerequisites

Before implementing risk screening, ensure you have:

* A Webacy API key ([sign up here](https://developers.webacy.co/billing))
* Basic familiarity with REST APIs or the [Webacy SDK](../sdk/installation)
* Your bot's trade execution flow identified for integration points

***

## Fast Token Screening

Speed is critical for trading bots. The Trading Lite API is optimized for sub-second decisions.

### Trading Lite API (Solana)

Get essential risk data in under 200ms.

<Warning>
  Trading Lite is currently available for **Solana only**. For EVM chains, use the standard contract analysis endpoints.
</Warning>

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://api.webacy.com/trading-lite/TokenMintAddress..." \
    -H "x-api-key: YOUR_API_KEY"
  ```

  ```typescript TypeScript theme={null}
  import { TradingClient, Chain } from '@webacy-xyz/sdk';

  const client = new TradingClient({ apiKey: process.env.WEBACY_API_KEY });

  const analysis = await client.tradingLite.analyze('PumpTokenMint...');

  // Quick decision
  const shouldBuy = analysis.riskScore < 40 &&
                    !analysis.isHoneypot &&
                    analysis.liquidity > 10000;

  if (shouldBuy) {
    console.log('✓ Token passed screening');
  } else {
    console.log('✗ Token failed screening');
    console.log(`  Risk: ${analysis.riskScore}, Honeypot: ${analysis.isHoneypot}`);
  }
  ```

  ```python Python theme={null}
  import requests

  response = requests.get(
      "https://api.webacy.com/trading-lite/TokenMintAddress...",
      headers={"x-api-key": "YOUR_API_KEY"}
  )
  analysis = response.json()

  # Quick decision
  should_buy = (
      analysis.get("riskScore", 100) < 40 and
      not analysis.get("isHoneypot", True) and
      analysis.get("liquidity", 0) > 10000
  )
  ```
</CodeGroup>

**Response fields:**

| Field         | Type    | Description              |
| ------------- | ------- | ------------------------ |
| `riskScore`   | number  | 0-100 overall risk score |
| `isHoneypot`  | boolean | Can you sell this token? |
| `liquidity`   | number  | Total liquidity in USD   |
| `holderCount` | number  | Number of token holders  |

### Honeypot Detection

The most critical check—don't buy what you can't sell.

```typescript theme={null}
interface TradeDecision {
  action: 'buy' | 'skip';
  reason: string;
  riskScore: number;
}

async function evaluateToken(mint: string): Promise<TradeDecision> {
  const analysis = await client.tradingLite.analyze(mint);

  // Immediate rejection: honeypot
  if (analysis.isHoneypot) {
    return {
      action: 'skip',
      reason: 'Honeypot detected - cannot sell',
      riskScore: 100,
    };
  }

  // Risk score threshold
  if (analysis.riskScore > 60) {
    return {
      action: 'skip',
      reason: `High risk score: ${analysis.riskScore}`,
      riskScore: analysis.riskScore,
    };
  }

  // Liquidity threshold
  if (analysis.liquidity < 5000) {
    return {
      action: 'skip',
      reason: `Insufficient liquidity: $${analysis.liquidity}`,
      riskScore: analysis.riskScore,
    };
  }

  return {
    action: 'buy',
    reason: 'Passed all checks',
    riskScore: analysis.riskScore,
  };
}
```

### Tax Detection

Hidden taxes can destroy profitability. A 10x gain means nothing with a 90% sell tax.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://api.webacy.com/contracts/0xTokenAddress.../tax?chain=eth" \
    -H "x-api-key: YOUR_API_KEY"
  ```

  ```typescript TypeScript theme={null}
  import { ThreatClient, Chain } from '@webacy-xyz/sdk';

  const threatClient = new ThreatClient({ apiKey: process.env.WEBACY_API_KEY });

  const tax = await threatClient.contracts.getTax(
    '0xTokenAddress...',
    { chain: Chain.ETH }
  );

  // Calculate effective profit threshold
  const buyTax = tax.buyTax / 100;
  const sellTax = tax.sellTax / 100;
  const taxDrag = 1 - ((1 - buyTax) * (1 - sellTax));

  console.log(`Total tax drag: ${(taxDrag * 100).toFixed(2)}%`);

  // Example: If buy tax is 5% and sell tax is 10%
  // You lose 5% on buy, then 10% of remaining on sell
  // Total drag: 1 - (0.95 * 0.90) = 14.5%

  if (taxDrag > 0.20) {
    console.log('⚠️ High tax drag - need significant price movement to profit');
  }
  ```

  ```python Python theme={null}
  response = requests.get(
      "https://api.webacy.com/contracts/0xTokenAddress.../tax",
      params={"chain": "eth"},
      headers={"x-api-key": "YOUR_API_KEY"}
  )
  tax = response.json()

  buy_tax = tax.get("buyTax", 0) / 100
  sell_tax = tax.get("sellTax", 0) / 100
  tax_drag = 1 - ((1 - buy_tax) * (1 - sell_tax))

  print(f"Total tax drag: {tax_drag * 100:.2f}%")
  ```
</CodeGroup>

**Tax thresholds for bots:**

| Scenario      | Max Tax   | Reasoning                     |
| ------------- | --------- | ----------------------------- |
| Scalping      | 3% total  | Need tight spreads            |
| Swing trading | 10% total | Can absorb some tax           |
| Long-term     | 15% total | Price appreciation covers tax |
| Never trade   | > 25%     | Likely scam                   |

***

## Sniper & Bundler Detection

Know what you're up against. If coordinated actors are already in, you're probably late.

### Holder Analysis

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://api.webacy.com/holder-analysis/TokenMint...?chain=sol" \
    -H "x-api-key: YOUR_API_KEY"
  ```

  ```typescript TypeScript theme={null}
  const holders = await client.holderAnalysis.get(
    'TokenMint...',
    { chain: Chain.SOL }
  );

  console.log(`Snipers: ${holders.sniperCount}`);
  console.log(`Bundlers: ${holders.bundlerCount}`);
  console.log(`Top 10 %: ${holders.top10Percentage}%`);

  // Sniper analysis
  if (holders.sniperCount > 5) {
    console.warn('⚠️ Heavy sniper activity - likely coordinated');
  }

  // Bundler analysis (multiple wallets acting as one)
  if (holders.bundlerCount > 2) {
    console.warn('⚠️ Bundler activity detected - insider accumulation');
  }

  // Concentration analysis
  if (holders.top10Percentage > 70) {
    console.warn('⚠️ High concentration - dump risk');
  }
  ```

  ```python Python theme={null}
  response = requests.get(
      "https://api.webacy.com/holder-analysis/TokenMint...",
      params={"chain": "sol"},
      headers={"x-api-key": "YOUR_API_KEY"}
  )
  holders = response.json()

  # Check for coordinated activity
  is_sniped = holders.get("sniperCount", 0) > 5
  has_bundlers = holders.get("bundlerCount", 0) > 2
  high_concentration = holders.get("top10Percentage", 0) > 70
  ```
</CodeGroup>

### Launch Screening

For new token launches, check the first buyers.

```typescript theme={null}
interface LaunchAnalysis {
  safeToEnter: boolean;
  sniperRisk: 'low' | 'medium' | 'high';
  bundlerRisk: 'low' | 'medium' | 'high';
  concentrationRisk: 'low' | 'medium' | 'high';
  reasons: string[];
}

async function analyzeLaunch(mint: string): Promise<LaunchAnalysis> {
  const holders = await client.holderAnalysis.get(mint, { chain: Chain.SOL });
  const reasons: string[] = [];

  // Evaluate sniper risk
  let sniperRisk: 'low' | 'medium' | 'high' = 'low';
  if (holders.sniperCount > 10) {
    sniperRisk = 'high';
    reasons.push(`${holders.sniperCount} snipers detected`);
  } else if (holders.sniperCount > 5) {
    sniperRisk = 'medium';
  }

  // Evaluate bundler risk
  let bundlerRisk: 'low' | 'medium' | 'high' = 'low';
  if (holders.bundlerCount > 3) {
    bundlerRisk = 'high';
    reasons.push(`${holders.bundlerCount} bundler clusters`);
  } else if (holders.bundlerCount > 1) {
    bundlerRisk = 'medium';
  }

  // Evaluate concentration risk
  let concentrationRisk: 'low' | 'medium' | 'high' = 'low';
  if (holders.top10Percentage > 80) {
    concentrationRisk = 'high';
    reasons.push(`Top 10 hold ${holders.top10Percentage}%`);
  } else if (holders.top10Percentage > 60) {
    concentrationRisk = 'medium';
  }

  // Overall decision
  const highRisks = [sniperRisk, bundlerRisk, concentrationRisk]
    .filter(r => r === 'high').length;

  const safeToEnter = highRisks === 0;

  return {
    safeToEnter,
    sniperRisk,
    bundlerRisk,
    concentrationRisk,
    reasons,
  };
}
```

***

## Liquidity Checks

Ensure you can exit your position.

### Pool Analysis

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://api.webacy.com/tokens/TokenAddress.../pools?chain=sol" \
    -H "x-api-key: YOUR_API_KEY"
  ```

  ```typescript TypeScript theme={null}
  const pools = await client.tokens.getPools(
    'TokenAddress...',
    { chain: Chain.SOL }
  );

  // Calculate total liquidity
  const totalLiquidity = pools.pools.reduce(
    (sum, pool) => sum + pool.liquidity,
    0
  );

  // Calculate safe position size (max 2% of liquidity)
  const maxPositionSize = totalLiquidity * 0.02;

  console.log(`Total liquidity: $${totalLiquidity.toLocaleString()}`);
  console.log(`Max safe position: $${maxPositionSize.toLocaleString()}`);

  // Check if position is viable
  const intendedPosition = 1000; // $1000
  if (intendedPosition > maxPositionSize) {
    console.warn(`⚠️ Position too large for liquidity`);
    console.warn(`  Intended: $${intendedPosition}, Max: $${maxPositionSize}`);
  }
  ```

  ```python Python theme={null}
  response = requests.get(
      "https://api.webacy.com/tokens/TokenAddress.../pools",
      params={"chain": "sol"},
      headers={"x-api-key": "YOUR_API_KEY"}
  )
  pools = response.json()

  total_liquidity = sum(p.get("liquidity", 0) for p in pools.get("pools", []))
  max_position = total_liquidity * 0.02  # 2% of liquidity

  print(f"Total liquidity: ${total_liquidity:,.2f}")
  print(f"Max safe position: ${max_position:,.2f}")
  ```
</CodeGroup>

### Slippage Estimation

```typescript theme={null}
function estimateSlippage(positionSize: number, liquidity: number): number {
  // Simple constant product formula approximation
  // Real slippage depends on pool type and depth distribution
  const impactRatio = positionSize / liquidity;
  const slippage = impactRatio * 100 * 2; // 2x for round trip

  return Math.min(slippage, 100); // Cap at 100%
}

// Usage
const liquidity = 50000; // $50k in pool
const position = 5000;   // $5k trade

const expectedSlippage = estimateSlippage(position, liquidity);
console.log(`Expected slippage: ~${expectedSlippage.toFixed(2)}%`);

// Decision threshold
if (expectedSlippage > 5) {
  console.warn('⚠️ High slippage expected - reduce position size');
}
```

***

## Complete Integration Workflow

### Bot Decision Flow

```mermaid theme={null}
flowchart TD
    A[Signal Detected] --> B{Trading Lite Check}
    B -->|Honeypot| C["❌ SKIP - Honeypot"]
    B -->|Risk > 60| D["❌ SKIP - High Risk"]
    B -->|Pass| E{Tax Check}
    E -->|Tax > 20%| F["❌ SKIP - High Tax"]
    E -->|Pass| G{Holder Analysis}
    G -->|Snipers > 10| H["⚠️ FLAG - Heavy sniping"]
    G -->|Top 10 > 80%| I["⚠️ FLAG - Concentrated"]
    G -->|Pass| J{Liquidity Check}
    H --> J
    I --> J
    J -->|Liq < Position * 50| K["❌ SKIP - Low liquidity"]
    J -->|Pass| L["✅ EXECUTE Trade"]
```

### Full TypeScript Implementation

<Accordion title="Complete Trading Bot Risk Engine">
  ```typescript theme={null}
  import { TradingClient, ThreatClient, Chain } from '@webacy-xyz/sdk';

  const tradingClient = new TradingClient({
    apiKey: process.env.WEBACY_API_KEY,
    defaultChain: Chain.SOL,
  });

  const threatClient = new ThreatClient({
    apiKey: process.env.WEBACY_API_KEY,
  });

  interface RiskEngineResult {
    shouldTrade: boolean;
    maxPositionUsd: number;
    riskScore: number;
    flags: string[];
    metrics: {
      liquidity: number;
      buyTax: number;
      sellTax: number;
      sniperCount: number;
      bundlerCount: number;
      top10Concentration: number;
    };
  }

  // Main risk engine function
  async function evaluateToken(
    tokenAddress: string,
    chain: Chain,
    intendedPositionUsd: number
  ): Promise<RiskEngineResult> {
    const flags: string[] = [];

    // Step 1: Quick check (Trading Lite for Solana, contract analysis for EVM)
    let quickCheck: { riskScore: number; isHoneypot: boolean; liquidity: number };

    if (chain === Chain.SOL) {
      quickCheck = await tradingClient.tradingLite.analyze(tokenAddress);
    } else {
      // EVM chains - use contract analysis
      const contract = await threatClient.contracts.analyze(tokenAddress, { chain });
      const pools = await tradingClient.tokens.getPools(tokenAddress, { chain });
      const totalLiquidity = pools.pools.reduce((sum, p) => sum + p.liquidity, 0);

      quickCheck = {
        riskScore: contract.overallRisk,
        isHoneypot: contract.isHoneypot ?? false,
        liquidity: totalLiquidity,
      };
    }

    // Immediate rejection: honeypot
    if (quickCheck.isHoneypot) {
      return {
        shouldTrade: false,
        maxPositionUsd: 0,
        riskScore: 100,
        flags: ['HONEYPOT DETECTED'],
        metrics: {
          liquidity: quickCheck.liquidity,
          buyTax: 0,
          sellTax: 100,
          sniperCount: 0,
          bundlerCount: 0,
          top10Concentration: 0,
        },
      };
    }

    // Step 2: Tax analysis (EVM only)
    let buyTax = 0;
    let sellTax = 0;

    if (chain !== Chain.SOL) {
      try {
        const tax = await threatClient.contracts.getTax(tokenAddress, { chain });
        buyTax = tax.buyTax;
        sellTax = tax.sellTax;

        if (sellTax > 25) {
          flags.push(`EXTREME SELL TAX: ${sellTax}%`);
        } else if (sellTax > 10) {
          flags.push(`High sell tax: ${sellTax}%`);
        }

        if (buyTax > 10) {
          flags.push(`High buy tax: ${buyTax}%`);
        }
      } catch {
        // Tax check failed - proceed with caution
        flags.push('Tax check unavailable');
      }
    }

    // Step 3: Holder analysis
    let sniperCount = 0;
    let bundlerCount = 0;
    let top10Concentration = 0;

    try {
      const holders = await tradingClient.holderAnalysis.get(tokenAddress, { chain });
      sniperCount = holders.sniperCount;
      bundlerCount = holders.bundlerCount;
      top10Concentration = holders.top10Percentage;

      if (sniperCount > 10) {
        flags.push(`Heavy sniping: ${sniperCount} snipers`);
      }

      if (bundlerCount > 3) {
        flags.push(`Bundler activity: ${bundlerCount} clusters`);
      }

      if (top10Concentration > 80) {
        flags.push(`High concentration: Top 10 hold ${top10Concentration}%`);
      }
    } catch {
      flags.push('Holder analysis unavailable');
    }

    // Step 4: Calculate max position based on liquidity
    const liquidity = quickCheck.liquidity;
    const maxPositionUsd = liquidity * 0.02; // 2% of liquidity

    if (intendedPositionUsd > maxPositionUsd) {
      flags.push(`Position too large for liquidity`);
    }

    if (liquidity < 5000) {
      flags.push(`Low liquidity: $${liquidity.toLocaleString()}`);
    }

    // Final decision
    const criticalFlags = flags.filter(f =>
      f.includes('EXTREME') ||
      f.includes('HONEYPOT') ||
      f.includes('Position too large')
    );

    const shouldTrade =
      !quickCheck.isHoneypot &&
      quickCheck.riskScore < 60 &&
      sellTax < 25 &&
      liquidity >= intendedPositionUsd * 50 &&
      criticalFlags.length === 0;

    return {
      shouldTrade,
      maxPositionUsd,
      riskScore: quickCheck.riskScore,
      flags,
      metrics: {
        liquidity,
        buyTax,
        sellTax,
        sniperCount,
        bundlerCount,
        top10Concentration,
      },
    };
  }

  // Batch evaluation for multiple tokens
  async function evaluateTokenBatch(
    tokens: Array<{ address: string; chain: Chain }>,
    positionSizeUsd: number
  ): Promise<Map<string, RiskEngineResult>> {
    const results = new Map<string, RiskEngineResult>();

    // Process in parallel (up to 10 at a time)
    const batchSize = 10;

    for (let i = 0; i < tokens.length; i += batchSize) {
      const batch = tokens.slice(i, i + batchSize);
      const batchResults = await Promise.all(
        batch.map(t => evaluateToken(t.address, t.chain, positionSizeUsd))
      );

      batch.forEach((token, index) => {
        results.set(token.address, batchResults[index]);
      });
    }

    return results;
  }

  // Pre-trade checklist
  async function preTradeCheck(
    tokenAddress: string,
    chain: Chain,
    positionUsd: number
  ): Promise<{
    approved: boolean;
    checklist: Array<{ check: string; passed: boolean; details: string }>;
  }> {
    const evaluation = await evaluateToken(tokenAddress, chain, positionUsd);

    const checklist = [
      {
        check: 'Not a honeypot',
        passed: evaluation.metrics.sellTax < 100,
        details: evaluation.metrics.sellTax >= 100 ? 'Cannot sell' : 'Sellable',
      },
      {
        check: 'Acceptable tax',
        passed: evaluation.metrics.sellTax < 15,
        details: `Buy: ${evaluation.metrics.buyTax}%, Sell: ${evaluation.metrics.sellTax}%`,
      },
      {
        check: 'Sufficient liquidity',
        passed: evaluation.metrics.liquidity >= positionUsd * 50,
        details: `$${evaluation.metrics.liquidity.toLocaleString()} available`,
      },
      {
        check: 'Not heavily sniped',
        passed: evaluation.metrics.sniperCount < 10,
        details: `${evaluation.metrics.sniperCount} snipers detected`,
      },
      {
        check: 'Not concentrated',
        passed: evaluation.metrics.top10Concentration < 80,
        details: `Top 10 hold ${evaluation.metrics.top10Concentration}%`,
      },
      {
        check: 'Risk score acceptable',
        passed: evaluation.riskScore < 60,
        details: `Score: ${evaluation.riskScore}/100`,
      },
    ];

    return {
      approved: checklist.every(c => c.passed),
      checklist,
    };
  }

  // Usage example
  async function main() {
    const token = 'PumpTokenMint...';
    const positionSize = 500; // $500

    const check = await preTradeCheck(token, Chain.SOL, positionSize);

    console.log('\nPre-Trade Checklist:');
    console.log('==================');

    for (const item of check.checklist) {
      const status = item.passed ? '✓' : '✗';
      console.log(`${status} ${item.check}: ${item.details}`);
    }

    console.log('==================');
    console.log(`Decision: ${check.approved ? 'APPROVED' : 'REJECTED'}`);
  }
  ```
</Accordion>

***

## Example Tokens for Testing

### Solana Tokens

Test against tokens from Pump.fun, Raydium, and Jupiter trending lists. Scam tokens are deployed constantly, so live data is the best test data.

### EVM Test Tokens

| Address                                      | Chain | Description          |
| -------------------------------------------- | ----- | -------------------- |
| `0xdAC17F958D2ee523a2206206994597C13D831ec7` | ETH   | USDT - safe, no tax  |
| `0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48` | ETH   | USDC - safe baseline |

<Info>
  **Testing tip**: For realistic testing, grab tokens from live trending feeds and run them through your risk engine. This gives you real data on current scam patterns.
</Info>

***

## Performance Optimization

### Caching Strategy

```typescript theme={null}
// Cache results to reduce API calls
const cache = new Map<string, { result: RiskEngineResult; timestamp: number }>();
const CACHE_TTL = 60 * 1000; // 1 minute

async function evaluateWithCache(
  tokenAddress: string,
  chain: Chain,
  positionUsd: number
): Promise<RiskEngineResult> {
  const cacheKey = `${tokenAddress}-${chain}`;
  const cached = cache.get(cacheKey);

  if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
    return cached.result;
  }

  const result = await evaluateToken(tokenAddress, chain, positionUsd);
  cache.set(cacheKey, { result, timestamp: Date.now() });

  return result;
}
```

### Parallel Processing

```typescript theme={null}
// Evaluate multiple tokens in parallel
async function batchEvaluate(
  tokens: string[],
  chain: Chain,
  positionUsd: number
): Promise<Map<string, RiskEngineResult>> {
  const results = await Promise.all(
    tokens.map(t => evaluateToken(t, chain, positionUsd))
  );

  return new Map(tokens.map((t, i) => [t, results[i]]));
}
```

***

## API Quick Reference

| Endpoint                         | Use Case             | Response Time |
| -------------------------------- | -------------------- | ------------- |
| `GET /trading-lite/{address}`    | Quick analysis (SOL) | \~200ms       |
| `GET /contracts/{address}`       | Contract analysis    | \~500ms       |
| `GET /contracts/{address}/tax`   | Tax detection        | \~300ms       |
| `GET /holder-analysis/{address}` | Holder distribution  | \~400ms       |
| `GET /tokens/{address}/pools`    | Liquidity pools      | \~300ms       |

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Get Your API Key" icon="key" href="https://developers.webacy.co/billing">
    Start screening tokens today
  </Card>

  <Card title="Trading Client SDK" icon="code" href="../sdk/trading-client">
    SDK for holder analysis
  </Card>

  <Card title="Honeypots Explained" icon="jar" href="../glossary/honeypots">
    Deep dive on honeypot mechanics
  </Card>

  <Card title="Snipers & Bundlers" icon="crosshairs" href="../glossary/snipers-bundlers">
    Understand coordinated trading
  </Card>
</CardGroup>
