Files
mev-beta/.claude/commands/audit-go-mev.md
2025-10-04 09:31:02 -05:00

9.8 KiB
Raw Permalink Blame History

Full Audit Checklist — Go MEV Arbitrage Bot

Scope: a production-grade Go service that scans mempool/RPCs, finds arbitrage, constructs & signs transactions, and submits them (e.g., direct RPC, Flashbots bundles). Includes any on-chain smart-contracts the bot depends on (adapters, helpers, custom contracts).


1) Planning & scoping (before running tools)

  • Identify attack surface: private keys, RPC/WS endpoints, mempool sources, bundle relays (Flashbots), third-party libs, config files.
  • Define assets at risk (max ETH / tokens), operational windows, and which chains/nodes (e.g., Arbitrum, Ethereum).
  • Create test accounts with funded testnet funds and a forked mainnet environment (Anvil/Hardhat/Foundry) for reproducible tests.

2) Static analysis — Go (SAST / linters / vuln DB)

Run these to find code smells, insecure patterns, and known vulnerable dependencies:

  • Tools to run: gosec, govulncheck, staticcheck, golangci-lint. (gosec and govulncheck are high-value for security.) ([GitHub][1])

Example commands:

# gosec
gosec ./...

# govulncheck (requires Go toolchain)
govulncheck ./...

# staticcheck via golangci-lint
golangci-lint run

What to look for:

  • Use of crypto/rand vs math/rand, insecure parsing of RPC responses, improper TLS skip verify, hard-coded secrets.
  • Unsafe use of sync primitives, race conditions flagged by go vet/staticcheck patterns.

3) Dynamic analysis & runtime checks — Go

  • Run go test with race detector and fuzzing (Go 1.18+ built-in fuzz):
# race detector
go test -race ./...

# fuzzing (example fuzz target)
go test -fuzz=Fuzz -fuzztime=10m ./...
  • Run integration tests on a mainnet-fork (Anvil/Foundry/Hardhat) so you can simulate chain state and mempool behaviours.
  • Instrument code with pprof and capture CPU/heap profiles during simulated high-throughput runs.

What to look for:

  • Race detector failures, panics, deadlocks, goroutine leaks (goroutines that grow unbounded during workload).

4) Go security & dependency checks

  • govulncheck (re: vulnerable dependencies). ([Go Packages][2])
  • Dependency graph: go list -m all and search for unmaintained or forked packages.
  • Check for unsafe cgo or native crypto libraries.

5) Code quality & architecture review checklist

  • Error handling: ensure errors are checked and wrapped (%w) not ignored.
  • Context: all network calls accept context.Context with deadlines/timeouts.
  • Modularization: separate mempool ingestion, strategy logic, transaction builder, and signer.
  • Testability: core arbitrage logic should be pure functions with injected interfaces for RPCs and time.
  • Secrets: private keys are never in repo, use a secrets manager (Vault / KMS) or env with restricted perms.

6) Concurrency & rate limiting

  • Ensure tight control over goroutine lifecycle (context cancellation).
  • Use worker pools for RPCs and bounded channels to avoid OOM.
  • Rate-limit RPC calls and implement backoff/retry strategies with jitter.

7) Transaction building & signing (critical)

  • Validate chain ID, EIP-155 protection, correct v,r,s values.
  • Nonce management: centralize nonce manager; handle failed/non-broadcast txs and re-sync nonces from node on error.
  • Gas estimation/testing: include sanity checks & max gas limits.
  • Signing: prefer hardware/remote signers (KMS, HSM). If local private keys used, ensure file perms and encryption.
  • Replay protection: verify chain ID usage and consider EIP-1559 parameterization (maxFeePerGas/maxPriorityFeePerGas).
  • If using Flashbots, validate bundle assembly and simulator checks (see Flashbots docs). ([Flashbots Docs][3])

8) Smart-contract audit (if you have custom contracts or interact closely)

Run this toolchain (static + dynamic + fuzz + formal):

  • Slither for static analysis.
  • Mythril (symbolic analysis) / MythX for additional SAST.
  • Foundry (forge) for unit & fuzz tests — Foundry supports fuzzing & is fast. ([Cyfrin][4])
  • Echidna for property-based fuzzing of invariants. ([0xmacro.com][5])
  • Consider Manticore/Mythril for deeper symbolic exploration, and Certora/formal approaches for critical invariants (if budget allows). ([Medium][6])

Example solidity workflow:

# slither
slither .

# Foundry fuzzing
forge test --fuzz

# Echidna (property-based)
echidna-test contracts/ --contract MyContract --config echidna.yaml

What to test:

  • Reentrancy, arithmetic over/underflow (if not using SafeMath / solidity ^0.8), access-control checks, unexpected token approvals, unchecked external calls.

9) Fuzzing — exhaustive plan

Go fuzzing

  • Use Gos native fuzz (go test -fuzz) for core libraries (parsers, ABI decoders, bundle builders).

  • Create fuzz targets focusing on:

    • RPC response parsing (malformed JSON).
    • ABI decoding and calldata construction.
    • Signed-transaction bytes parser.
  • Run for long durations with corpus seeding from real RPC responses.

Solidity fuzzing

  • Use Foundrys forge test --fuzz and Echidna to target invariants (balances, no-negative slippage, token conservation).
  • Seed fuzzers with historical tx traces & typical call sequences.

Orchestration

  • Run fuzzers in CI but also schedule long runs in a buildkite/GitHub Actions runner or dedicated machine.
  • Capture crashes/inputs and convert them to reproducible testcases.

References and how-to guides for solidity fuzzing and Foundry usage. ([Cyfrin][4])


10) Penetration-style tests / adversarial scenarios

  • Mempool-level adversary: inject malformed or opponent transactions, test how bot reacts to reorgs & chain reorganizations.
  • Time/latency: simulate delayed RPC responses and timeouts.
  • Partial failures: simulate bundle reverts, tx replaced, or gas price spikes.
  • Economic tests: simulate price or liquidity slippage, oracle manipulation scenarios.

11) Monitoring, metrics & observability

  • Add structured logs (JSON), trace IDs, and use OpenTelemetry or Prometheus metrics for:

    • latency from detection → tx submission,
    • success/failure counters,
    • gas usage per tx,
    • nonce mismatches.
  • Add alerts for repeated reorgs, high failure rates, or sudden profit/loss anomalies.

  • Simulate alerting (PagerDuty/Slack) in staging to ensure operational readiness.


12) CI/CD & reproducible tests

  • Integrate all static and dynamic checks into CI:

    • gosec, govulncheck, golangci-lint → fail CI on new high/critical findings.
    • Unit tests, fuzzing smoke tests (short), Foundry tests for solidity.
  • Store fuzzing corpora and reproduce minimized crashing inputs in CI artifacts.


13) Secrets & deployment hardening

  • Never commit private keys or mnemonic in code or config. Use secret manager (AWS KMS / GCP KMS / HashiCorp Vault).
  • Use least-privilege for node credentials; isolate signer service from other components.
  • Harden nodes: avoid public shared RPCs for production signing; prefer dedicated provider or local node.

14) Reporting format & remediation plan (what the auditor should deliver)

  • Executive summary: risk posture and amount at risk.

  • Prioritized findings: Critical / High / Medium / Low / Informational.

    • For each finding: description, evidence (stack trace, log snippets, test reproducer), impact, exploitability, and line-level references.
    • Fix recommendation: code patch or test to cover the case; include sample code where relevant.
  • Re-test plan: how to validate fixes (unit/regression tests, fuzzing seeds).

  • Follow-up: suggested schedule for re-audit (post-fix) and continuous scanning.


15) Severity guidance (example)

  • Critical: fund-loss bug; private key compromised; unsigned tx broadcast leak.
  • High: nonce desync under normal load; reentrancy in helper contract called by bot.
  • Medium: panic on malformed RPC response; unbounded goroutine leak.
  • Low: logging missing request IDs; non-idiomatic error handling.
  • Informational: code style, minor refactors.

16) Example concrete test cases to include

  • RPC returns truncated JSON → does the bot panic or gracefully retry?
  • Node returns nonce too low mid-run → does the bot resync or keep retrying stale nonce?
  • Simulate mempool reordering and reorg of 2 blocks → does bot detect revert & recover?
  • Flashbots bundle simulator returns revert on one tx → ensure bot doesnt double-submit other txs.
  • ABI-decoder fuzzed input causing unexpected panic in Go (fuzzer should find).

17) Example commands / CI snippets (condensed)

# .github/workflows/ci.yml (snippets)
- name: Lint & Security
  run: |
    golangci-lint run ./...
    gosec ./...
    govulncheck ./...

- name: Unit + Race
  run: go test -race ./...

- name: Go Fuzz (short)
  run: go test -run TestFuzz -fuzz=Fuzz -fuzztime=1m ./...

18) Deliverables checklist for the auditor (what to hand back)

  • Full report (PDF/Markdown) with prioritized findings & diffs/patches.
  • Repro scripts for each failing case (docker-compose or Foundry/Anvil fork commands).
  • Fuzzing corpora and minimized crashing inputs.
  • CI changes / workflow proposals for enforcement.
  • Suggested runtime hardening & monitoring dashboard templates.

  • gosec — Go security scanner. ([GitHub][1])
  • govulncheck — Go vulnerability scanner for dependencies. ([Go Packages][2])
  • Foundry (forge) — fast solidity testing + fuzzing. ([Cyfrin][4])
  • Echidna — property-based fuzzing for Solidity. ([0xmacro.com][5])
  • Slither / Mythril — solidity static analysis & symbolic analysis. ([Medium][6])

  • Run a full audit (code + solidity + fuzzing) before mainnet launch.
  • Keep continuous scanning (gosec/govulncheck) in CI on every PR.
  • Schedule quarterly security re-checks + immediate re-audit for any major dependency or logic change.