VegaSec / Solidity scan report

Reentrance.sol

VSS-20260527-6IS84164 · generated May 27, 2026, 7:07 AM

Clear surface · automated4 findings1 highPasted sourcesemgrep 1.163.0

Verdict is derived from severity counts via the same deterministic formula every VegaSec report uses. Reentrance.sol was scanned from pasted source. This is static-analysis triage, not a certification or formal audit attestation.

Signature

unsigned

This report has no signature. It was persisted before report signing shipped, so nobody can prove authorship for it, including us. The bytes can still be hashed to check that they did not change.

PDF artifact

Queued artifact pipeline · not blocking on the scan

Not requested

No PDF artifact has been requested for this report yet. The HTML report and the Markdown export already carry the full disclaimer and limitations inline. PDF synthesis is a queued artifact, not part of the scan path.

Status endpoint

GET /report/solidity/VSS-20260527-6IS84164/export.pdf

Solidity evidence report

4 audit findings

high: 0medium: 0informational: 0

Severity distribution

semgrep 1.163.0
  • highReentrancyConfidence: unknownExploitability: unknownDetector: slither

    Reentrancy in Reentrance.withdraw(uint256) (Reentrance.sol#3):

    Affected location
    Reentrance.sol:3
    Detector / source
    slither · slither:reentrancy-eth

    Evidence

    Reentrancy in Reentrance.withdraw(uint256) (Reentrance.sol#3): External calls: - (ok,None) = msg.sender.call{value: amount}() (Reentrance.sol#3) State variables written after the call(s): - balances[msg.sender] -= amount (Reentrance.sol#3) Reentrance.balances (Reentrance.sol#3) can be used in cross function reentrancies: - Reentrance.balances (Reentrance.sol#3) - Reentrance.deposit() (Reentrance.sol#3) - Reentrance.withdraw(uint256) (Reentrance.sol#3)

    Exploitability notes

    Static analysis did not prove exploitability; do not present this as an exploit claim.

    Remediation

    No automated remediation hint is available. Escalate this finding for manual review before making a public claim.

    Limitations

    • Analyzer did not report confidence; fail closed and treat the finding as unverified.
    • Static analysis did not prove exploitability; do not present this as an exploit claim.
    • Analyzer output did not include a source excerpt for this finding.
  • mediumUnchecked callConfidence: unknownExploitability: unknownDetector: semgrep

    Low-level

    Affected location
    Reentrance.sol:3
    Detector / source
    semgrep · semgrep:vegasec-low-level-call-untrusted

    Evidence

    Low-level .call to an externally-controlled target. Combined with reentrancy or unchecked return values, this is a common fund-draining pattern.

    Exploitability notes

    Static analysis did not prove exploitability; do not present this as an exploit claim.

    Remediation

    No automated remediation hint is available. Escalate this finding for manual review before making a public claim.

    Limitations

    • Analyzer did not report confidence; fail closed and treat the finding as unverified.
    • Static analysis did not prove exploitability; do not present this as an exploit claim.
    • Analyzer output did not include a source excerpt for this finding.
  • informationalLogicConfidence: unknownExploitability: unknownDetector: slither

    Version constraint 0.8.19 contains known severe issues (https://solidity.readthedocs.io/en/latest/bugs.html)

    Affected location
    Reentrance.sol:2
    Detector / source
    slither · slither:solc-version

    Evidence

    Version constraint 0.8.19 contains known severe issues (https://solidity.readthedocs.io/en/latest/bugs.html) - VerbatimInvalidDeduplication - FullInlinerNonExpressionSplitArgumentEvaluationOrder - MissingSideEffectsOnSelectorAccess. It is used by: - 0.8.19 (Reentrance.sol#2)

    Exploitability notes

    Static analysis did not prove exploitability; do not present this as an exploit claim.

    Remediation

    No automated remediation hint is available. Escalate this finding for manual review before making a public claim.

    Limitations

    • Analyzer did not report confidence; fail closed and treat the finding as unverified.
    • Static analysis did not prove exploitability; do not present this as an exploit claim.
    • Analyzer output did not include a source excerpt for this finding.
  • informationalUnchecked callConfidence: unknownExploitability: unknownDetector: slither

    Low level call in Reentrance.withdraw(uint256) (Reentrance.sol#3):

    Affected location
    Reentrance.sol:3
    Detector / source
    slither · slither:low-level-calls

    Evidence

    Low level call in Reentrance.withdraw(uint256) (Reentrance.sol#3): - (ok,None) = msg.sender.call{value: amount}() (Reentrance.sol#3)

    Exploitability notes

    Static analysis did not prove exploitability; do not present this as an exploit claim.

    Remediation

    No automated remediation hint is available. Escalate this finding for manual review before making a public claim.

    Limitations

    • Analyzer did not report confidence; fail closed and treat the finding as unverified.
    • Static analysis did not prove exploitability; do not present this as an exploit claim.
    • Analyzer output did not include a source excerpt for this finding.

Exploit reasoning

Reference-grade reasoning tied to evidence

  • 10071287073f93fcc57b572abfd9512b7d6d8adc6702c7d51ec1c82aaf616cb6 · reentrancyhigh
    Confidence: unknown

    Exploitability is not determined; the entry stays UNKNOWN until operator review.

    Preconditions

    • External call to an untrusted address before the contract's own state is updated
    • Contract or callback path reachable from the external caller
    • No nonReentrant guard or equivalent on the entry-point function

    Action

    Attacker contract receives control during the external call and re-enters the original function before the original state write completes, repeating the state-changing side effect.

    Impact

    Duplicated withdrawals, double-spend on accounting balances, or out-of-order updates to invariants the function relies on.

    False-positive caveats

    • The external call may be to a known, trusted contract whose behavior is provable.
    • The function may be guarded indirectly by a flag or external lock not visible to the analyzer.

    Remediation checklist

    • Apply checks-effects-interactions: update internal state before any external call.
    • Add a nonReentrant guard on the entry-point function.
    • Where feasible, pull-payment instead of push-payment on user balances.
  • 6f4ae2520fdeb83172fc21910d2241de1e45af07969313bc381bec79fadea17a · unchecked-callmedium
    Confidence: unknown

    Exploitability is not determined; the entry stays UNKNOWN until operator review.

    Preconditions

    • Low-level call (`.call`, `.delegatecall`, `.send`) whose return value is ignored
    • Subsequent logic assumes the call succeeded

    Action

    Attacker forces the called contract to fail (out of gas, revert) so the outer function keeps accounting for state the call never wrote.

    Impact

    Funds marked as transferred that never moved; balances debited without the corresponding credit.

    False-positive caveats

    • Some unchecked sends are intentional (best-effort fee distribution).
    • Return value may be checked indirectly via reentrancy guards or balance assertions.

    Remediation checklist

    • Require the return value of `.call()` / `.send()` and revert on failure.
    • Prefer `.transfer()` only for low-gas pure transfers; otherwise use OpenZeppelin Address.functionCall.
    • Add tests covering recipient-revert paths.

Report badges

Verified source

Badges describe the evidence carried by this report artifact, not financial value or future pricing. Operator-reviewed is never granted automatically.

How to read this report

Score, confidence, ranking: four moving parts, no hand-tuning.

Generated May 27, 2026, 7:07 AM · Solidity · Reentrance.sol

Score bands

  • 0-19

    AVOID-style triage

    Multiple high or critical findings, low source confidence, or unverified context. Public action should pause until a Private Review or a re-scan with better evidence.

  • 20-49

    High caution

    Notable findings or thin evidence. Worth a Private Review before relying on the artifact.

  • 50-69

    Watch

    Mixed signals: some evidence, some gaps. Re-scan after material changes to the target.

  • 70-89

    Clear surface (automated) · this report

    No critical or high findings via static analysis. Not a safety claim: human review is still recommended for diligence work.

  • 90-100

    Strong surface (automated)

    No critical or high findings, verified source, and high source confidence. Not a safety claim: human review is still recommended for diligence work.

Score
Deterministic 0-100 derived from severity counts. Same formula across every report. Lower means more risk.
Confidence
Separate axis. Measures how much VegaSec trusts the input data. Low confidence pushes the verdict toward UNKNOWN; the two are never collapsed into one number.
Ranking / percentile
Only meaningful within the eligible Trust Index set. Shown on /trust-index when the eligible pool is large enough. Today the public index is a controlled preview.

Private Review is separate

A paid Private Review does not raise the public score on this report. Public score reflects public-source evidence only. Private Review adds operator attestation and a confidential memo, never a score bump.

Export and share

  • · Shareable public URL: copy from the report actions panel.
  • · Markdown export: every export carries the report id, target, verdict, generated timestamp, and the public-data disclaimer.
  • · PDF export: not in this MVP. Tracked as a follow-up. The Markdown export contains the same content and prints cleanly to PDF from a browser today.

Source provenance

This report scanned a Solidity source provided directly by the submitter (paste). No on-chain address is associated.

Scanned source (382 chars)

// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;
contract Reentrance { mapping(address => uint256) public balances; function deposit() external payable { balances[msg.sender] += msg.value; } function withdraw(uint256 amount) external { require(balances[msg.sender] >= amount); (bool ok, ) = msg.sender.call{value: amount}(""); require(ok); balances[msg.sender] -= amount; } }

Public-data disclaimer

Solidity scans are triage based on slither + semgrep static analysis. Output is not a certification, audit attestation or financial advice. Findings can include false positives and may miss patterns the configured detectors do not cover.