mcpField
S
sybil-detection

sybil-detection

github.com/agiprolabsデータ・データベース456445 回インストール8 週間前に更新
リポジトリ

sybil-detection について

Solana トークン市場の協調ウォレットや偽装された活動を分析するスキルです。資金源、同時取引、バンドル取引などを手掛かりに、Sybil クラスターや人為的な需要の兆候を検出します。

主な機能

  1. 01保有者ウォレットの資金源を追跡
  2. 02同時取引とバンドル買いを検出
  3. 03ウォッシュ取引と作成者との関連を分析
  4. 04Sybil リスク指標をスコア化
  5. 05クラスター検出・資金追跡スクリプト

活用シーン

  1. 01トークン保有者が関連ウォレットかを評価
  2. 02初期買いにバンドルや協調がないか確認
  3. 03取引量や保有者数の偽装を調査

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/agiprolabs/claude-trading-skills --skill sybil-detection

インストール後、Claude Code で/sybil-detectionを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
bundler_detection.md
clustering_methods.md
scripts/
detect_sybils.py
funding_tracer.py

詳細

Sybil Detection — 協調されたウォレットと偽のアクティビティの分析

Solana のトークン市場における Sybil 攻撃では、単一の主体が多数のウォレットを操作し、自然なアクティビティを装います。このスキルでは、協調しているウォレットのクラスター、ウォッシュトレーディング、バンドルされたトランザクション、偽の保有者数の水増しを検出します。これは、トークンの指標が実際の需要を反映しているのか、人為的に作られたシグナルなのかを評価するうえで重要です。

Sybil 検出が重要な理由

Solana のトークン市場には、人為的に作られたシグナルがあふれています。

  • 水増しされた保有者数:500 人の「保有者」が、実際にはそれぞれ 50 個のウォレットを持つ 10 の主体である
  • 偽の取引量:自己管理ウォレット間のウォッシュトレーディングで需要を演出する
  • 人為的なソーシャルプルーフ:多くのウォレットで少額ずつ保有し、広く分散しているように見せる
  • ラグプルの準備:作成者が供給量を多数のウォレットに分散させ、その後、協調して売却する
  • バンドルされたローンチ:PumpFun トークンで、作成者が最初のスロットで Jito バンドルを通じて購入する

保有者が 1,000 人いて、その 80%が 3 つのウォレットから資金提供されているトークンと、独立した資金源を持つ 1,000 人の保有者がいるトークンは、根本的に異なります。Sybil 検出によって、実際の需要と見せかけを区別できます。

検出カテゴリ

1. 資金提供元の分析

各保有者ウォレットを 1~2 ホップさかのぼり、SOL の送金元を特定します。

import httpx

def trace_funding_source(wallet: str, api_key: str, max_hops: int = 2) -> list[str]:
    """Trace SOL funding sources for a wallet via Helius parsed transactions."""
    url = f"https://api.helius.xyz/v0/addresses/{wallet}/transactions"
    resp = httpx.get(url, params={"api-key": api_key, "type": "TRANSFER", "limit": 50})
    transfers = resp.json()

    funders = []
    for tx in transfers:
        for transfer in tx.get("nativeTransfers", []):
            if transfer["toUserAccount"] == wallet and transfer["amount"] > 0.001 * 1e9:
                funders.append(transfer["fromUserAccount"])
    return funders

主なシグナル:

  • 3 つ以上の保有者ウォレットに同じ送金元から資金提供されている=クラスター
  • トークン作成から 24 時間以内に資金提供されている=疑いが強い
  • 資金提供額が同一(例:各ウォレットに 0.05 SOL)=自動化された分配
2. 同時取引パターン

ほぼ同時刻に同じトークンを購入するウォレットは、協調している可能性が高いです。

def detect_co_trades(buy_events: list[dict], slot_window: int = 3) -> list[list[str]]:
    """Group wallets that bought within the same slot window."""
    buy_events.sort(key=lambda x: x["slot"])
    clusters = []
    current_cluster = [buy_events[0]]

    for i in range(1, len(buy_events)):
        if buy_events[i]["slot"] - current_cluster[0]["slot"] <= slot_window:
            current_cluster.append(buy_events[i])
        else:
            if len(current_cluster) >= 3:
                clusters.append([b["wallet"] for b in current_cluster])
            current_cluster = [buy_events[i]]

    if len(current_cluster) >= 3:
        clusters.append([b["wallet"] for b in current_cluster])
    return clusters

解釈:

  • 同じスロット内の別々のトランザクション=協調(ボット主導)
  • 同じトランザクション=バンドル(Sybil であることが確実)
  • トークン作成後の最初の 3 スロット=ローンチスナイピングのクラスター
3. バンドルされたトランザクション

複数の購入を 1 つの Solana トランザクションまたは Jito バンドルにまとめたものです。

def check_bundle_ratio(early_buys: list[dict], bundle_window_slots: int = 5) -> dict:
    """Calculate the ratio of bundled vs independent early buys."""
    bundled = [b for b in early_buys if b.get("is_bundled", False)]
    first_slot = min(b["slot"] for b in early_buys) if early_buys else 0
    early = [b for b in early_buys if b["slot"] - first_slot <= bundle_window_slots]

    return {
        "total_early_buys": len(early),
        "bundled_buys": len(bundled),
        "bundle_ratio": len(bundled) / max(len(early), 1),
        "bundled_supply_pct": sum(b["amount"] for b in bundled) / max(sum(b["amount"] for b in early), 1),
    }

PumpFun 固有のパターンと Jito バンドルの仕組みについては、references/bundler_detection.md を参照してください。

4. ウォッシュトレーディングの検出

同一の主体が複数のウォレットを通じて売買し、取引量を水増しします。

シグナル:

  • ウォレット A がトークンを購入してウォレット B に転送し、ウォレット B が売却する――循環的な資金の流れ
  • 複数のウォレットが互いに売買を繰り返し、ネットポジションに変化がない
  • 資金提供元に関連があるウォレットのペアに取引量が集中している
def detect_wash_cycles(transfers: list[dict], holder_set: set[str]) -> list[tuple]:
    """Find circular transfer patterns among known holders."""
    # Build directed graph of transfers between holders
    edges: dict[tuple, float] = {}
    for t in transfers:
        if t["from"] in holder_set and t["to"] in holder_set:
            key = (t["from"], t["to"])
            edges[key] = edges.get(key, 0) + t["amount"]

    # Find reciprocal pairs (A->B and B->A both exist)
    wash_pairs = []
    for (a, b), vol_ab in edges.items():
        vol_ba = edges.get((b, a), 0)
        if vol_ba > 0:
            wash_pairs.append((a, b, vol_ab, vol_ba))
    return wash_pairs
5. 作成者ネットワークの分析

トークン作成者が管理するウォレットを特定します。

  • 作成者ウォレットの資金提供履歴から、作成者が資金提供した他のウォレットを特定できます
  • それらのウォレットがトークン供給量を保有している=インサイダーによる分配
  • 作成者が「別の」ウォレットから売却している=偽装された売り抜け

主な指標

指標計算式健全要注意重大
資金提供元が一意な割合unique_funders / total_holders> 0.80.4-0.8< 0.4
資金提供クラスターの規模max(cluster_sizes)< 55-20> 20
同時取引スコアwallets_in_first_3_slots / total_holders< 0.10.1-0.3> 0.3
バンドル比率bundled_buys / total_early_buys< 0.10.1-0.4> 0.4
バンドルされた供給量の割合bundled_token_amount / total_supply_sold< 5%5-20%> 20%
転送密度internal_transfers / total_transfers< 0.10.1-0.3> 0.3
ウォッシュトレードのペア数reciprocal_pairs / total_holder_pairs01-3 pairs> 3 pairs

複合リスクスコア

個々のシグナルを組み合わせ、単一の Sybil リスクスコア(0~100)を算出します。

def compute_sybil_score(metrics: dict) -> dict:
    """Compute composite sybil risk score from individual metrics."""
    weights = {
        "funding_cluster": 25,    # Wallets from same funder
        "co_trade": 20,           # Coordinated buy timing
        "bundle_ratio": 20,       # Bundled early transactions
        "unique_funder": 15,      # Diversity of funding sources
        "transfer_density": 10,   # Internal transfers between holders
        "wash_trade": 10,         # Circular trading patterns
    }

    scores = {}
    # Each sub-score normalized to 0-1, then weighted
    scores["funding_cluster"] = min(metrics.get("max_cluster_size", 0) / 20, 1.0)
    scores["co_trade"] = min(metrics.get("co_trade_pct", 0) / 0.3, 1.0)
    scores["bundle_ratio"] = min(metrics.get("bundle_ratio", 0) / 0.5, 1.0)
    scores["unique_funder"] = 1.0 - min(metrics.get("unique_funder_ratio", 1.0), 1.0)
    scores["transfer_density"] = min(metrics.get("transfer_density", 0) / 0.3, 1.0)
    scores["wash_trade"] = min(metrics.get("wash_pairs", 0) / 5, 1.0)

    composite = sum(scores[k] * weights[k] for k in weights)
    risk_level = "LOW" if composite < 30 else "MEDIUM" if composite < 60 else "HIGH"

    return {"score": round(composite, 1), "risk_level": risk_level, "components": scores}

データソース

ソース提供データ認証
Helius のパース済みトランザクション資金提供履歴、転送の詳細、パース済み命令データAPI キー(無料枠:30 req/s)
SolanaTracker APIバンドル検出、保有者リスト、トークンメタデータAPI キー
Solana RPC (getSignaturesForAddress)任意のウォレットの生のトランザクション署名RPC URL
Solana RPC (getTokenLargestAccounts)残高上位の保有者RPC URL
DexScreenerクロスリファレンス用の基本的なトークン/ペアデータ不要

トークンを評価するワークフロー

# 1. Get top holders
holders = get_top_holders(token_mint, rpc_url)

# 2. Trace funding sources for each holder
funding_map = {}
for wallet in holders[:30]:  # Top 30 is usually sufficient
    funding_map[wallet] = trace_funding_source(wallet, helius_key)

# 3. Cluster by common funder
clusters = cluster_by_funder(funding_map)

# 4. Check co-trade timing
early_buys = get_early_buy_events(token_mint, helius_key)
co_trade_groups = detect_co_trades(early_buys)

# 5. Check for bundles
bundle_stats = check_bundle_ratio(early_buys)

# 6. Check wash trading
transfers = get_token_transfers(token_mint, helius_key)
wash_pairs = detect_wash_cycles(transfers, set(holders))

# 7. Compute composite score
metrics = {
    "max_cluster_size": max(len(c) for c in clusters) if clusters else 0,
    "co_trade_pct": sum(len(g) for g in co_trade_groups) / len(holders),
    "bundle_ratio": bundle_stats["bundle_ratio"],
    "unique_funder_ratio": len(set(f for fs in funding_map.values() for f in fs)) / len(holders),
    "transfer_density": len(wash_pairs) / max(len(holders), 1),
    "wash_pairs": len(wash_pairs),
}
result = compute_sybil_score(metrics)
print(f"Sybil Risk: {result['risk_level']} ({result['score']}/100)")

他のスキルとの連携

  • token-holder-analysis:保有者リストを入力として使用します。シビル検出によりクラスターのコンテキストが加わります
  • helius-api:パース済みトランザクション履歴の主要なデータソースです
  • jito-bundles:バンドルの詳細な検出とMEVのコンテキストを提供します
  • liquidity-analysis:シビルスコアと組み合わせます。流動性が低く、シビルスコアが高い場合は極めて高いリスクです
  • whale-tracking:実際の大口保有者とシビルクラスターの集計を区別します

ファイル

ファイル説明
references/clustering_methods.md資金源のクラスタリング、同時取引のタイミング分析、グラフベースの検出手法
references/bundler_detection.mdバンドルされたトランザクションの検出、PumpFunのパターン、Jitoのバンドルの仕組み
scripts/detect_sybils.pyシビル検出の完全なパイプライン:保有者 -> 資金調達 -> クラスター -> リスクスコア
scripts/funding_tracer.pyウォレット群の資金源を追跡し、共通の祖先ごとにグループ化します

コメント