A ghost fill on Polymarket costs you real money. GhostGuard catches every one within seconds of the fill.
You're running a maker bot on Polymarket V1 or V2. You've seen fills that make no sense β price moved wrong, size doesn't match, position tracker goes out of sync. Some of those are ghost fills. Over time they compound into serious PnL leak.
GhostGuard is a detection layer you run alongside your existing bot (any language β Rust, Python, Node, Go). On every CLOB fill, it verifies the on-chain settlement. If the settlement reverted, you get an instant webhook: stop trading, cancel exposed orders, investigate.
It's a smoke alarm, not a fire extinguisher. Real prevention requires migrating to an EIP-1271 smart contract wallet with cancel registry. GhostGuard is the detection layer you run while you decide whether to migrate β or permanently, as a second verification line if you do migrate.
Rust crate + CLI tool that detects ghost fills on Polymarket's CLOB.
A ghost fill occurs when the CLOB reports an order as filled, but the on-chain settlement transaction reverts. This costs market makers real money. GhostGuard monitors fills and verifies each one on-chain, catching ghosts in real time.
Real-time terminal dashboard showing fill verification, predictive warnings, and market stats. Run with --tui flag.
CLOB fill event ββ> extract tx_hash ββ> poll eth_getTransactionReceipt
β
βββββββββββΌβββββββββββ
β β β
status=1 status=0 no receipt
REAL GHOST TIMEOUT
β (treat as ghost)
β
parse revert reason
(TRANSFER_FROM_FAILED, etc.)
Three known attack variants all produce the same on-chain result (status=0):
- incrementNonce() -- invalidates order signature before settlement
- Wallet drain -- transfers USDC out before settlement, tx reverts with
TRANSFER_FROM_FAILED - Gas front-running -- outbids the settlement tx
GhostGuard detects the result, not the method.
curl -L https://raw.githubusercontent.com/orderbooktrade/GhostGuard/main/ghostguardup | bashThis downloads the prebuilt binary for your platform to ~/.ghostguard/bin and adds it to your PATH. Works on macOS (Intel/Apple Silicon) and Linux (x86_64/ARM64).
cargo install --git https://github.com/OrderBookTrade/GhostGuardgit clone https://github.com/OrderBookTrade/GhostGuard
cd GhostGuard
make install[dependencies]
ghostguard = { git = "https://github.com/OrderBookTrade/GhostGuard" }ghostguard --versionghostguard \
--verify-tx 0x9e3230abde0f569da87511a6f8823076f7b211bb00d10689db3b7c50d6652df0This is a known ghost fill (wallet drain, TRANSFER_FROM_FAILED). Output:
[GHOST] tx=0x9e32...2df0 reason=TRANSFER_FROM_FAILED
counterparty=0x4bfb...982e
ghostguard \
--rpc https://polygon-rpc.com \
--clob-ws wss://ws-subscriptions-clob.polymarket.com/ws/market \
--webhook http://localhost:8080/fill-alertListens to the CLOB websocket for fills, verifies each on-chain, and:
- Logs to stdout:
[REAL]or[GHOST]with tx details - POSTs JSON to your webhook URL on every verdict
ghostguard \
--config ghostguard.toml \
--tui \
--predictiveuse ghostguard::{GhostGuard, Config};
let config = Config {
rpc_url: "https://polygon-rpc.com".into(),
clob_ws_url: "wss://ws-subscriptions-clob.polymarket.com/ws/market".into(),
..Default::default()
};
let mut guard = GhostGuard::new(config);
guard.on_real_fill(|verdict| {
// safe to update position state
});
guard.on_ghost_fill(|event| {
eprintln!("GHOST: {} -- {}", event.tx_hash, event.reason);
// trigger recovery: cancel open orders, alert ops, etc.
});
guard.start().await?;You can also verify a single tx directly:
use ghostguard::{verify_fill, Config, FillVerdict};
let verdict = verify_fill(&config.rpc_url, tx_hash, &config).await?;
if verdict.is_ghost() {
// handle ghost fill
}ghostguard [OPTIONS]
Options:
--rpc <URL> Polygon JSON-RPC endpoint [default: https://polygon-rpc.com]
--clob-ws <URL> CLOB WebSocket URL [default: wss://ws-subscriptions-clob...]
--webhook <URL> Webhook URL to POST verdicts to
--timeout <SECS> Verification timeout in seconds [default: 10]
--poll-ms <MS> Receipt poll interval in milliseconds [default: 500]
--verify-tx <HASH> Verify a single tx hash and exit
-h, --help Print help
-V, --version Print version
src/
lib.rs Public API -- GhostGuard struct, re-exports
types.rs Config, FillVerdict, GhostFillEvent, contract addresses
verifier.rs Core logic -- polls receipt, parses revert, returns verdict
ws.rs CLOB websocket listener, parses fill messages
callback.rs Webhook POST dispatcher
bin/cli.rs CLI sidecar binary
examples/
basic.rs Minimal usage with known ghost tx
enum FillVerdict {
Real { tx_hash: H256, block: u64 },
Ghost { tx_hash: H256, reason: String, counterparty: Option<Address> },
Timeout { tx_hash: H256 },
}
struct GhostFillEvent {
tx_hash: H256,
market: String,
side: String,
size: f64,
price: f64,
counterparty: Option<Address>,
reason: String,
timestamp: u64,
}On each fill, GhostGuard POSTs JSON to your webhook:
{
"verdict": "Ghost",
"tx_hash": "0x9e3230ab...",
"reason": "TRANSFER_FROM_FAILED",
"counterparty": "0x4bfb41d5..."
}| Contract | Address |
|---|---|
| CTF Exchange | 0x4bfb41d5b3570defd03c39a9a4d8de6bd8b8982e |
| NegRisk CTF Exchange | 0xC5d563A36AE78145C45a50134d48A1215220f80a |
| USDC.e (Polygon) | 0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174 |
# Unit tests
cargo test
# Integration test against live Polygon RPC
cargo test -- --ignored test_known_ghost_fill
# Run the example
cargo run --example basicGhostGuard is currently in beta. I'm onboarding 3-5 production market makers for free integration in exchange for feedback:
- 30-min setup call to wire GhostGuard into your existing bot
- Direct DM access during beta (I debug issues with you)
- Your ghost fill history analysis over the past 30 days
- Pricing locks in after beta β early access makers get 50% off first year
Who this is for: You're running a live MM bot with real capital, you've had at least one weird fill you couldn't fully explain, and you want a second pair of eyes on your settlement layer.
How to apply: DM me on Polymarket Discord (@Bruce) or Telegram (@iambaice) with:
- Your bot's stack (language, markets, daily volume range)
- One example of a fill you couldn't explain
I reply within 24 hours.
- GhostGuard subscription: real-time detection + webhook + dashboard. Starting at $299/month for single-wallet tracking.
- Custom integration: I wire GhostGuard into your existing bot stack, tune alerts to your strategy. $2,500 one-time.
- Polymarket consulting: architecture review, exploit post-mortem, V2 migration planning. $150/hour.
MIT
