スキル一覧に戻る
scalus3

smart-contract-security-review

by scalus3

smart-contract-security-reviewは、other分野における実用的なスキルです。複雑な課題への対応力を強化し、業務効率と成果の質を改善します。

98🍴 14📅 2026年1月23日
GitHubで見るManusで実行

SKILL.md


name: smart-contract-security-review description: Security review for Scalus/Cardano smart contracts. Analyzes @Compile annotated validators for vulnerabilities like redirect attacks, inexact value validation, missing token verification, integer overflow, and self-dealing. Use when reviewing on-chain code, before deploying validators, or when /security-review is invoked. Requires explicit path argument.

Smart Contract Security Review

Analyze Scalus/Cardano smart contracts for security vulnerabilities.

Target Code Identification

Find on-chain code by searching for:

  1. Objects/classes with @Compile annotation
  2. Objects extending Validator, DataParameterizedValidator, or ParameterizedValidator
  3. Objects compiled with PlutusV3.compile(), PlutusV2.compile(), or PlutusV1.compile()

Search patterns:

grep -rn "@Compile" --include="*.scala" <path>
grep -rn "extends Validator" --include="*.scala" <path>
grep -rn "extends DataParameterizedValidator" --include="*.scala" <path>

Workflow

  1. Discovery: Find all @Compile annotated code in specified path
  2. Classification: Identify validator type (spend/mint/reward/certify/vote/propose)
  3. Analysis: Check each validator against vulnerability checklist
  4. False Positive Verification: For each potential issue, verify it's not a false positive
  5. Reporting: Generate structured report with severity levels (only verified issues)
  6. Remediation: Use TodoWrite to track issues, fix one-by-one with user confirmation

Vulnerability Checklist

Based on Cardano Developer Portal security guidelines and Scalus-specific patterns. For detailed patterns and code examples, see references/vulnerabilities.md.

Critical Severity

IDNameRiskDetection
V001Redirect AttackFunds stolen via output redirectionoutputs.at(idx) without address validation
V002Token/NFT Not VerifiedState token excludedMissing quantityOf on outputs
V003Inexact Burn/MintExtra tokens minted>= instead of === for quantities
V004Integer OverflowArithmetic overflowCustom encoding without bounds
V005Double SatisfactionPay once, satisfy manyoutputs.exists without unique linking

High Severity

IDNameRiskDetection
V006Index Validation MissingInvalid index access.at(idx) without bounds check
V007Self-Dealing/Shill BiddingPrice manipulationNo seller/bidder separation
V008Double Spend via IndexSame UTxO processed twiceIndex lists without uniqueness
V009Inexact Refund AmountFund manipulation>= for refunds instead of ===
V010Other Redeemer AttackBypass via different redeemerMultiple script purposes
V011Other Token Name AttackUnauthorized token mintingPolicy doesn't check all tokens
V012Missing UTxO AuthenticationFake UTxO injectionNo auth token verification
V025Oracle Data ValidationPrice manipulation, stale dataOracle data without signature/freshness

Medium Severity

IDNameRiskDetection
V013Time HandlingTime manipulationIncorrect interval bounds
V014Missing SignatureUnauthorized actionsNo isSignedBy checks
V015Datum MutationUnauthorized state changeNo field comparison
V016Insufficient Staking ControlReward redirectionNo staking credential check
V017Arbitrary DatumUnspendable UTxOsNo datum validation
V024Parameterization VerificationScript substitution (varies)ParameterizedValidator with auth params, no token

Low Severity / Design Issues

IDNameRiskDetection
V018Unbounded ValueUTxO size limitUnlimited tokens in output
V019Unbounded DatumResource exhaustionGrowing datum size
V020Unbounded InputsTX limit exceededMany required UTxOs
V021UTxO Contention / Concurrency DoSBottleneck, DoSShared global state, no rate limit
V022Cheap Spam/DustOperation obstructionNo minimum amounts
V023Locked ValuePermanent lockMissing exit paths

False Positive Verification

CRITICAL: Before reporting ANY vulnerability, you MUST verify exploitability by tracing code execution with a concrete attack transaction.

Verification Method: Attack Transaction Tracing

For each potential vulnerability:

  1. Construct a concrete attack transaction

    • Define specific inputs (UTxOs with concrete values/datums)
    • Define the redeemer values
    • Define the outputs the attacker would create
    • Define signatories
  2. Execute the validator logic mentally with this transaction

    • Go line-by-line through the validator code
    • Track what each variable evaluates to with your attack tx
    • Check EVERY require() statement - does it pass or fail?
  3. If ANY require fails, the attack fails → False Positive

  4. Only report if ALL requires pass with the attack transaction

Example: V005 Double Satisfaction Verification

Potential vulnerability detected: handlePay uses getAdaFromOutputs(sellerOutputs) without unique linking.

Construct attack transaction:

Inputs:
  - EscrowA: 12 ADA, datum={seller=S, buyer=B, escrowAmount=10, initAmount=2}
  - EscrowB: 12 ADA, datum={seller=S, buyer=B, escrowAmount=10, initAmount=2}
Outputs:
  - 12 ADA to seller S (single output for both!)
  - 1 ADA to buyer B
Signatories: [B]

Trace execution for EscrowA:

// Line 57-58:
val contractInputs = txInfo.findOwnInputsByCredential(contractAddress.credential)
// → Returns [EscrowA, EscrowB] (both have same script credential)

val contractBalance = Utils.getAdaFromInputs(contractInputs)
// → 12 + 12 = 24 ADA

// Line 118-120 in handlePay:
require(contractBalance === escrowDatum.escrowAmount + escrowDatum.initializationAmount)
// → require(24 === 10 + 2)
// → require(24 === 12)
// → FAILS! ❌

Result: Attack transaction fails at line 118-120. This is a FALSE POSITIVE.

When to Write a Test

If the attack trace is complex or you're uncertain, write an actual test:

test("V005: Double satisfaction attack should fail") {
  // Setup: Create two escrow UTxOs with same seller
  val escrowA = createEscrowUtxo(seller = S, buyer = B, amount = 10.ada)
  val escrowB = createEscrowUtxo(seller = S, buyer = B, amount = 10.ada)

  // Attack: Try to spend both with single output to seller
  val attackTx = Transaction(
    inputs = List(escrowA, escrowB),
    outputs = List(TxOut(sellerAddress, 12.ada)),  // Only pay once!
    redeemers = Map(escrowA -> Pay, escrowB -> Pay)
  )

  // Verify: Should this pass or fail?
  // If it passes → Real vulnerability
  // If it fails → False positive
  evaluateValidator(EscrowValidator, escrowA, attackTx) shouldBe failure
}

Verification Checklist

Before reporting, answer these questions:

QuestionAnswer Required
What is the specific attack transaction?Inputs, outputs, redeemers, signatories
Which line would the attacker exploit?File:line reference
Did you trace through EVERY require in the code path?Yes/No
Does the attack pass ALL requires?Yes (report) / No (false positive)
What value does the attacker gain?Concrete amount/asset

Do NOT Report If

  • You only found a pattern match without tracing execution
  • You haven't constructed a specific attack transaction
  • Any require() in the code path would fail the attack
  • You're unsure whether the attack works (investigate more or write a test)

Output Format

Use clickable file_path:line_number format for all code locations.

Finding Format

For each vulnerability found, output in this format:

### [SEVERITY] ID: Vulnerability Name

**Location:** `full/path/to/File.scala:LINE`
**Method:** methodName

**Issue:** Brief description of what's wrong

**Vulnerable code** (`full/path/to/File.scala:LINE-LINE`):
```scala
// actual code from file

Fix:

// proposed fix


### Summary Table

At the end, provide a summary with clickable locations:

Summary

IDSeverityLocationIssueStatus
C-01Criticalpath/File.scala:123Missing mint validationFixed
H-01Highpath/File.scala:87Token not in outputDeclined
M-01Mediumpath/File.scala:200Missing signatureFalse Positive

False Positives

IDLocationReason
M-01path/File.scala:200Authorization is done via NFT ownership in verifyAuth helper

Security Grade: A/B/C/D/F


### Location Format Rules

1. Always use full path from project root: `scalus-examples/jvm/src/.../File.scala:123`
2. For ranges use: `File.scala:123-145`
3. For method references: `File.scala:123` (methodName)
4. Make locations clickable by using backticks

## Interactive Workflow

For each finding:
1. Display issue with location and proposed fix
2. Prompt: "Apply fix? [y/n/s/d/f]"
   - y: Apply fix, mark completed, verify with `sbtn compile`
   - n: Skip, log as "declined"
   - s: Skip without logging
   - d: Show more details (attack scenario)
   - f: Mark as false positive (prompts for reason, logged to summary)
3. After all findings: run `sbtn quick` to verify fixes
4. Generate summary report including:
   - Fixed issues
   - Declined issues
   - False positives with reasons

## Reference

For detailed vulnerability patterns and code examples, see:
- `references/vulnerabilities.md` - Full pattern documentation with Scalus-specific examples

スコア

総合スコア

70/100

リポジトリの品質指標に基づく評価

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

+10
説明文

100文字以上の説明がある

0/10
人気

GitHub Stars 100以上

0/15
最近の活動

1ヶ月以内に更新

+10
フォーク

10回以上フォークされている

+5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

+5

レビュー

💬

レビュー機能は近日公開予定です