The full upstream README, mirrored here for reference. Install config, tool schemas, adoption signals, and an original overview live on the Aikido MCP listing page.
Security analysis platform for Aiken smart contracts on Cardano.
Aikido goes beyond static analysis. It combines a 75-detector suite with SMT verification, transaction simulation, compliance analysis, protocol pattern detection, and grammar-aware fuzzing to find vulnerabilities in Aiken smart contracts before they reach mainnet. Multi-lane analysis cross-correlates evidence across techniques, producing findings with source context, severity ratings, CWE/CWC classifications, and actionable remediation guidance.
Built in Rust. Fast. Zero configuration required.
Cardano smart contracts are immutable once deployed. A vulnerability in production means lost funds with no recourse. Manual audits are expensive, slow, and bottlenecked. Aikido catches the classes of bugs that auditors find most often - double satisfaction, missing signature checks, unbounded iteration, unsafe datum handling - automatically, in seconds.
Aikido uses a multi-lane approach where independent analysis techniques cross-validate each other:
| Lane | What it does |
|---|---|
| Detector Suite | Cross-module interprocedural analysis, taint tracking, symbolic execution, delegation-aware suppression, transitive signal merging, datum continuity tracking |
| Compliance | Securify2-style dual-pattern system: every security property has compliance (safe) and violation (unsafe) patterns. 10 security property variants |
| SMT Verification | Solver-independent interface with Cardano domain axioms (value conservation, signature semantics, minting policy). Constraint solving for reachability |
| Tx Simulation | ScriptContext builder generates concrete exploit scenarios. Tests 6 detector categories against simulated transactions |
| Protocol Detection | Automatic DeFi protocol classification (DEX, Lending, Staking, DAO, NFT, Options, Escrow). Token flow and authority analysis |
| Fuzz Lane | Grammar-aware Cardano transaction generation, Echidna-style stateful protocol fuzzing, deterministic PRNG |
Supporting modules: CWC Registry (30 entries mapping all 75 detectors), Scorecard (Experimental -> Beta -> Stable promotion with quality gates), SSA IR (phi nodes, dominators, use-def chains).
Aikido was benchmarked against TxPipe's professional audit of Strike Finance (perpetuals + forwards contracts):
| Metric | Result |
|---|---|
| TxPipe security findings analyzed | 24 |
| Full match (true positive) | 12 |
| Partial match | 5 |
| Correctly not flagged (code fixed) | 4 |
| False negatives | 3 |
| Aikido unique findings | 26 |
| Coverage (unfixed findings) | 85% |
Full methodology and per-finding breakdown: AUDIT_COMPARISON.md
Validated against 10+ real-world Aiken smart contract projects with zero crashes:
| Project | Findings | Severity Distribution |
|---|---|---|
| SundaeSwap DEX | 47 | 1 critical, 13 high, 24 medium, 3 low, 6 info |
| Anastasia Design Patterns | 24 | 3 critical, 10 high, 8 medium, 2 low, 1 info |
| Anastasia Multisig | 6 | 2 critical, 4 medium |
| Seedelf Wallet | 4 | 1 high, 2 medium, 1 low |
| Strike Finance (4 repos) | 75 | 5 critical, 18 high, 40 medium, 8 low, 4 info |
| Acca | 20 | 20 medium |
| Total | 176 | 81% estimated true positive rate |
75 detectors mapped to CWE identifiers.
| Detector | CWE | Description |
|---|---|---|
double-satisfaction | CWE-362 | Spend handler iterates outputs without referencing own input |
missing-minting-policy-check | CWE-862 | Mint handler doesn't validate which token names are minted |
missing-utxo-authentication | CWE-345 | Reference inputs used without authentication |
unrestricted-minting | CWE-862 | Minting policy with no authorization check at all |
output-address-not-validated | CWE-20 | Outputs sent to unchecked addresses |
| Detector | CWE | Description |
|---|---|---|
missing-redeemer-validation | CWE-20 | Catch-all redeemer pattern trivially returns True |
missing-signature-check | CWE-862 | Authority datum fields with no extra_signatories check |
unsafe-datum-deconstruction | CWE-252 | Option datum not safely deconstructed with expect Some |
missing-datum-in-script-output | CWE-404 | Script output without datum attachment (funds locked forever) |
arbitrary-datum-in-output | CWE-20 | Outputs produced without validating datum correctness |
division-by-zero-risk | CWE-369 | Division with attacker-controlled denominator |
token-name-not-validated | CWE-20 | Mint policy checks auth but not token names |
value-not-preserved | CWE-682 | Spend handler doesn't verify output value >= input value |
unsafe-match-comparison | CWE-697 | Value compared with match instead of structural equality |
integer-underflow-risk | CWE-191 | Subtraction on redeemer-controlled values |
quantity-of-double-counting | CWE-682 | Token quantity checked without isolating input vs output |
state-transition-integrity | CWE-20 | Redeemer actions without datum transition validation |
withdraw-zero-trick | CWE-863 | Withdraw handler exploitable with zero-value withdrawal |
other-token-minting | CWE-862 | Mint policy allows minting tokens beyond intended scope |
unsafe-redeemer-arithmetic | CWE-682 | Arithmetic on redeemer-tainted values without bounds |
value-preservation-gap | CWE-682 | Lovelace checked but native assets not preserved |
uncoordinated-multi-validator | CWE-362 | Multi-handler validator without cross-handler coordination |
missing-burn-verification | CWE-862 | Token burning without proper verification |
oracle-manipulation-risk | CWE-20 | Oracle data used without manipulation safeguards |
| Detector | CWE | Description |
|---|---|---|
missing-validity-range | CWE-613 | Time-sensitive datum without validity_range check |
insufficient-staking-control | CWE-863 | Outputs don't constrain staking credential |
unbounded-datum-size | CWE-400 | Datum fields with unbounded types (List, ByteArray) |
unbounded-value-size | CWE-400 | Outputs don't constrain native asset count |
unbounded-list-iteration | CWE-400 | Direct iteration over raw transaction list fields |
oracle-freshness-not-checked | CWE-613 | Oracle data used without recency verification |
non-exhaustive-redeemer | CWE-478 | Redeemer match doesn't cover all constructors |
hardcoded-addresses | CWE-798 | ByteArray literals matching Cardano address lengths |
utxo-contention-risk | CWE-400 | Single global UTXO contention pattern |
cheap-spam-vulnerability | CWE-770 | Validator vulnerable to cheap UTXO spam |
unsafe-partial-pattern | CWE-252 | Expect pattern on non-Option type that may fail at runtime |
unconstrained-recursion | CWE-674 | Self-recursive handler without clear termination |
empty-handler-body | CWE-561 | Handler with no meaningful logic |
unsafe-list-head | CWE-129 | list.head() / list.at() without length guard |
missing-datum-field-validation | CWE-20 | Spend handler accepts datum fields but never validates them |
missing-token-burn | CWE-862 | Minting policy with no burn handling |
missing-state-update | CWE-665 | State machine without datum update |
rounding-error-risk | CWE-682 | Integer division on financial values |
missing-input-credential-check | CWE-862 | Input iteration without credential check |
duplicate-asset-name-risk | CWE-694 | Minting without unique asset name enforcement |
fee-calculation-unchecked | CWE-682 | Fee or protocol payment without validation |
datum-tampering-risk | CWE-20 | Datum passed through without field-level validation |
missing-protocol-token | CWE-862 | State transition without protocol token verification |
unbounded-protocol-operations | CWE-400 | Both input and output lists iterated without bounds |
| Detector | Severity | Description |
|---|---|---|
reference-script-injection | Low | Outputs don't constrain reference_script field |
unused-validator-parameter | Low | Validator parameter never referenced |
fail-only-redeemer-branch | Low | Redeemer branch that always fails |
missing-min-ada-check | Info | Script output without minimum ADA check |
dead-code-path | Low | Unreachable code paths |
redundant-check | Low | Trivially true conditions |
shadowed-variable | Info | Handler parameter shadowed by pattern binding |
magic-numbers | Info | Unexplained numeric literals |
excessive-validator-params | Info | Too many validator parameters |
unused-import | Info | Imported module with no function calls |
Each detector has detailed documentation with vulnerable examples, safe examples, and remediation guidance. Use aikido --explain <detector-name> or see docs/detectors/.
9 formats for different workflows:
.aikido.tomlRequires Rust >= 1.88.0.
Detectors are derived from real vulnerabilities found in published Cardano smart contract audits:
| Source | Findings Covered |
|---|---|
| MLabs audit reports | Double satisfaction, missing minting policy, arbitrary datum, unbounded size |
| Vacuumlabs audit reports | Unbounded value size, token dust attacks |
| Plutonomicon | Unrestricted minting, double satisfaction patterns |
| Anastasia Labs audit reports | Staking credential theft, datum handling |
| TxPipe audit reports | Oracle manipulation, state transition integrity, value preservation |
| CWE Database | 75 detectors mapped to specific CWE identifiers |
MIT