← Back to Blog

How to Detect Sybil Wallets: A Developer Guide

by WalletIQ Team

Sybil attacks cost protocols millions. When one person creates hundreds of wallets to claim an airdrop multiple times, legitimate users get diluted and the token distribution fails its purpose. Here’s how to detect and filter sybils programmatically.

What Makes a Wallet a Sybil?

Sybil wallets share common patterns that distinguish them from organic users:

  • Young age — created shortly before the airdrop snapshot
  • Low activity diversity — few unique contracts, repetitive transaction patterns
  • Minimal value — small balances, just enough to cover gas
  • Single-chain — no cross-chain activity
  • No DeFi history — no protocol interactions beyond basic transfers
  • Clustered behavior — similar transaction timing and amounts across wallets

No single signal is conclusive, but combining multiple signals creates a reliable sybil score.

Detection Strategy

The most effective approach uses a scoring model with weighted signals:

Signal 1: Wallet Age

Real users have history. Sybil wallets are typically less than 90 days old at snapshot time.

import { WalletIQ } from "walletiq";

const wiq = new WalletIQ({ apiKey: "wiq_..." });
const profile = await wiq.getProfile(address);

// Flag: wallet younger than 90 days
const isYoung = profile.age.days < 90;

Signal 2: Transaction Diversity

Legitimate users interact with many contracts. Sybils interact with one or two (the qualifying contracts for the airdrop).

// Flag: fewer than 5 unique contracts
const isLowDiversity = profile.stats.uniqueContractsInteracted < 5;

Signal 3: Multi-Chain Activity

Real DeFi users operate across multiple chains. Sybils usually stick to one.

// Flag: active on only 1 chain
const isSingleChain = profile.chains.length === 1;

Signal 4: DeFi Protocol Usage

Organic users have DeFi history — swaps, lending, staking. Sybils typically don’t.

// Flag: no DeFi protocol interactions
const noDeFi = profile.defi.protocols.length === 0;

Signal 5: Risk Score

WalletIQ’s built-in risk score combines age, activity, diversity, and known patterns into a 0-100 score. Higher means riskier.

// Flag: risk score above 60
const isHighRisk = profile.risk.score > 60;

Signal 6: Behavioral Labels

WalletIQ automatically labels wallets based on behavior patterns. Specific labels are strong sybil indicators:

// Flag: has sybil-associated labels
const sybilLabels = ["new-wallet", "repetitive-pattern"];
const hasSybilLabels = profile.labels.some(l => sybilLabels.includes(l));

Combining Signals

Weight each signal and sum them. A threshold determines eligibility:

function sybilScore(profile) {
  let score = 0;

  if (profile.age.days < 90) score += 25;
  if (profile.stats.uniqueContractsInteracted < 5) score += 20;
  if (profile.chains.length === 1) score += 15;
  if (profile.defi.protocols.length === 0) score += 15;
  if (profile.risk.score > 60) score += 15;
  if (profile.labels.includes("repetitive-pattern")) score += 10;

  return score; // 0-100, higher = more likely sybil
}

const score = sybilScore(profile);
const isSybil = score >= 50; // threshold

Putting It Together

Here’s a complete filtering function that processes a list of addresses:

import { WalletIQ } from "walletiq";

const wiq = new WalletIQ({ apiKey: "wiq_..." });

async function filterSybils(addresses, threshold = 50) {
  const results = [];

  for (const address of addresses) {
    const profile = await wiq.getProfile(address);
    const score = sybilScore(profile);

    results.push({
      address,
      score,
      eligible: score < threshold,
      labels: profile.labels,
      age: profile.age.days,
    });
  }

  return results.filter(r => r.eligible);
}

Recommended Thresholds

ThresholdEffectBest for
30Strict — filters aggressivelyHigh-value airdrops (>$100/wallet)
50Balanced — catches most sybilsStandard airdrops
70Lenient — only catches obvious botsCommunity-focused drops

Tips

  • Don’t rely on a single signal. Age alone catches legitimate new users. Combine at least 3 signals.
  • Test your thresholds against known-good addresses before deploying.
  • Use the playground to manually inspect edge cases: walletiq.dev/playground
  • Cache profiles — WalletIQ caches for 5 minutes. Batch your lookups efficiently.

Ready to filter sybils from your airdrop? Get a free API key and start with 100 lookups/month.

Ready to integrate wallet intelligence?

Get Free API Key