DeFi Security Alliance

Chains

Vyper contract audit: compiler evidence, tool limits and application scope

Compiler assurance and application assurance answer different questions. A Vyper contract audit must connect the source, compiler settings and deployed behavior while checking language-specific protections and known advisories.

Coiled glass tube on a workbench with a row of tools ending at an empty slot, representing the tooling gaps in auditing Vyper contracts.

Key facts

Compiler index
18 linked review entries at the measured revision
Limited-review marker
10 of 18 filenames explicitly say limited review
Formats
17 PDF entries and 1 Markdown competitive report
Tool boundary
Slither supports Vyper; Echidna documents limited support

Language differences that matter to the audit

A Vyper contract audit must identify the compiler and application behavior being reviewed, rather than treating Vyper as Solidity with different syntax. Language restrictions can make some code paths easier to inspect, but the generated bytecode, dependency behavior and economic assumptions still require evidence.

Vyper's design documentation excludes features such as Solidity-style modifiers, class inheritance and inline assembly to improve readability and constrain misleading control flow. That design does not make the language immune to compiler bugs or application errors. Nor does the absence of class inheritance mean a project has no modules, imports or external dependencies.

Start with visibility and mutability.

The opened documentation distinguishes external functions, internal functions and deployment code. A view function can read state without changing it, while a mutable function may update state. The review should establish the actual externally reachable surface and how imported code participates in it.

Nonreentrancy behavior is version-specific.

Current documentation describes a global lock shared by protected functions and a file-scoped pragma available beginning with version 0.4.2. That pragma can enable protection for external functions and eligible public getters in the file. It is off by default in the opened reference, so the compiler version alone does not prove it was enabled.

Inspect exceptions and imports.

The documentation states that imported files retain their own nonreentrancy behavior and that explicit reentrant declarations can permit a particular path. A source review should therefore record the pragma and decorators where they actually apply. A claim that the whole project is nonreentrant needs more than one protected entry point.

Language evidence to retain in the release packet
PropertyWhat to inspectUnsupported shortcut
Entry-point visibilityExternal, internal and deployment declarationsAssuming every function is externally reachable
MutabilityState reads, writes and external-call constraintsTreating a view result as economically trustworthy
Lock behaviorCompiler version, pragma and decoratorsAssuming a language-wide protection is always on
DependenciesImports, modules and external interfacesEquating no class inheritance with no dependencies
Generated behaviorBuild settings and runtime bytecodeTreating source readability as compiler correctness

Vyper design principles and the function and nonreentrancy reference support these distinctions.

Tooling gaps: verify the supported operation, not just the language label

The current Slither README explicitly describes support for both Solidity and Vyper.

Calling it a Solidity-only tool would be inaccurate. The useful question is narrower: does the installed version support your compiler output, project structure and the particular analysis being requested?

Echidna's README lists limited Vyper support.

That is a reason to verify the exact harness and integration, not to report that all Vyper fuzzing is impossible. A tool can accept compiled bytecode while providing different source mapping or language-specific analysis support. Preserve the behavior actually exercised by the run.

Titanoboa provides a Vyper-oriented execution environment.

Its README explains that it uses Vyper as a library to compile source and runs bytecode through an instrumented EVM implementation. That offers useful introspection, but the audit still needs to identify the execution rules, compiler configuration and any instrumentation assumptions relevant to the result.

A successful installation is not a successful security check.

Record which files compiled, which analyses ran and which portions were skipped or unsupported. A process that exits without findings after failing to load the target does not establish a clean result. Keep setup failures separate from contract findings.

Tool evidence opened for this review
ToolDocumented capability or limitEvidence to request from the engagement
SlitherSolidity and Vyper static-analysis frameworkVersion, target compilation and detectors actually run
EchidnaREADME lists limited Vyper supportWorking harness and the exact properties exercised
TitanoboaVyper compilation with instrumented executionCompiler, execution configuration and reproducible tests
Vyper compilerLayout and multiple output formatsPinned settings and generated artifacts

Slither's current README, Echidna's documented limitations and Titanoboa's architecture description are the primary references for those claims.

For a multi-language protocol, review the interfaces between components.

A Vyper contract can depend on an external asset or adapter implemented in another language. Tests should preserve the actual calling and return-value expectations rather than replacing every dependency with a permissive mock.

Code coverage also needs interpretation. Executing a line can establish that a test reached it, but it does not show that the relevant adversarial state was explored. Pair coverage with named properties for accounting, authorization and failure handling. An unsupported analyzer should create a documented evidence gap and a replacement review method, not an unexplained omission.

This article did not execute these tools against a production contract. The descriptions are grounded in their opened documentation. A commissioned audit should provide its own commands, versions and outputs for the actual candidate. That distinction keeps a tooling recommendation from becoming a claim of tested compatibility.

The 2023 compiler incident: match the affected build, not the source appearance

The Vyper advisory GHSA-5824-cm3x-3c38 documents a reentrancy-lock allocation problem in compiler versions 0.2.15, 0.2.16 and 0.3.0. The issue gave functions separate locks even when they used the same named key. A source reader could see the intended shared protection while the generated behavior failed to supply it.

The advisory's conditions matter. It describes a primary function using a named nonreentrancy key, an external call before relevant effects and another function whose behavior can be affected by the inconsistent state. An affected compiler version is therefore an exposure indicator to investigate; it is not sufficient by itself to prove that every compiled contract has an exploitable path.

The advisory identifies 0.3.1 as the patch for this issue. That statement must not be expanded into a recommendation that this old version is the current safest compiler or free from all known bugs. Compiler selection should consider the current advisory list, release requirements and the target chain.

A compiler release does not change already deployed bytecode. A project must identify the artifacts built with an affected compiler and determine which of them expose the relevant path. The available response then depends on deployment authority, migration options and the integrations that consume the contract.

Exposure review for the named compiler advisory
EvidenceQuestionRequired distinction
Compiler versionWas the deployed artifact built by an affected version?A repository setting may differ from the actual build
Lock declarationsWhich functions were intended to share protection?Source intent and emitted behavior can differ
External-call sequenceCan control leave before the relevant state is complete?A version match alone is not an exploit
Cross-function pathCan the callback use inconsistent state elsewhere?Same-function testing may miss the relevant route
Deployment optionsCan the affected artifact be replaced or retired?Publishing a compiler patch does not patch production

The Vyper security advisory provides the affected versions and conditions. The reentrancy test matrix shows how to map those conditions to callback paths.

Preserve negative results as well as confirmed exposure. A contract may use an affected compiler but lack the required callback path under its supported dependencies. That conclusion needs a bounded analysis of those dependencies and configuration, not an assumption that the decorator must work.

Historical code samples also need a version label. Earlier Vyper releases used named keys, while the opened current documentation describes a global lock. Mixing the old annotation syntax with a current-language explanation can make a review checklist internally inconsistent. Keep the version and the property together in both tests and report prose.

Our compiler-review inventory: 18 entries with different scopes

We inventoried every report entry under a year heading in the compiler-maintained Vyper audit index at a pinned revision. The index contains 18 entries across the listed years. Ten filenames explicitly identify a limited review. Counting all entries as independent full-compiler audits would therefore overstate what the index describes.

Method

Source
Vyper audit index
Retrieved
Selection
All linked report entries under year headings in the pinned README. Introductory firm links are excluded.
Unit
One index entry, including the competitive report and limited reviews.
Scope signal
The literal limited_review filename marker. Absence of that marker is not proof of full coverage.
Revision
The survey output retains the exact repository commit and raw index text.

Results

Vyper review-index counts by year and document attribute
Year or attributeEntriesDenominator
2022118 index entries
2023818 index entries
2024618 index entries
2025318 index entries
Filenames marked limited review1018 index entries
PDF report links1718 index entries

The remaining entry is a Markdown competitive-audit report. The index names ChainSecurity, OtterSec, Statemind, Anatomist and CodeHawks across its entries. These are publisher or platform labels in the index, not a count of independent teams that reviewed every compiler subsystem.

Limits

  • The inventory counts the index, not every review that may exist elsewhere.
  • Report entries can cover a feature, release candidate, fix review or limited subsystem.
  • The census did not execute compiler tests or independently reproduce report findings.
  • Listed years describe the index entries and do not establish the latest compiler release date.

Reproduction uses seo/research/vyper-audit-index-survey.py; its dated output is seo/research/vyper-audit-index-survey-2026-09-05.json. These files remain in the repository and are not published as downloads. The output preserves source responses, retrieval outcomes and the selection rules for later verification.

Audit scoping for Vyper: separate compiler and application evidence

The application scope should identify the source revision, compiler build, optimization mode and target execution rules. Vyper's compilation documentation exposes settings and outputs relevant to that record. A source file without its build context is insufficient for comparing a reviewed candidate with deployed runtime bytecode.

Preserve both deployment and runtime artifacts. Constructor or deployment arguments can install a different administrator or dependency even when the runtime source looks familiar. A bytecode comparison should explain the metadata and configuration it accounts for rather than asserting equivalence from a superficial text match.

Optimization belongs in the record. The compiler documentation describes modes that prioritize code size or gas differently. The audit does not need to assume an optimizer is faulty to require a reproducible build. It needs the settings that produced the actual behavior under review.

Review storage layout where state persists across a transition. The compiler can emit layout information, but a structural output does not prove that a migration preserves application meaning. Existing balances, lock state and privileged roles may need explicit before-and-after assertions. This is especially relevant when a dependency or compiler change alters storage assumptions.

Separate compiler assurance from application assurance in the report. An audit of a compiler subsystem can support confidence in that subsystem under its scope. It does not evaluate your collateral policy, oracle integration or administrator permissions. Conversely, an application audit may rely on a specified compiler without re-auditing the compiler itself.

Vyper application scope packet
ArtifactPurposeAcceptance question
Source and importsDefine the candidate implementationCan the reviewer reconstruct the exact project?
Compiler and settingsDefine generated behaviorDoes the build reproduce the expected artifacts?
Deployment configurationDefine installed authority and dependenciesDoes production match the reviewed setup?
Property testsDefine intended accounting and authorizationWere the meaningful adversarial paths exercised?
Advisory assessmentDefine known compiler exposureAre affected conditions present in the deployment?
Residual-risk recordDefine the assurance boundaryWhich compiler or integration assumptions remain?

Vyper compilation and layout documentation explains the build evidence. The upgrade review guide covers state transitions when the deployment supports replacement.

Vyper release evidence spans source and execution The path connects source semantics, then compiler artifact, then deployed behavior. Each stage carries a different acceptance condition.Source semanticsImports and protectionsCompiler artifactPinned settingsDeployed behaviorConfiguration and tests
Readable source, reproducible compilation and deployed behavior answer different parts of the audit question.
Source semantics
Imports and protections.
Compiler artifact
Pinned settings.
Deployed behavior
Configuration and tests.

For an immutable deployment, record the response that remains possible if a compiler issue is confirmed. It may involve restricting an integration, migrating users or retiring an affected component. The audit should not promise an in-place repair when no authorized replacement path exists. Establish the practical options before a production incident forces the decision.

Firms with Vyper experience: request the relevant artifact

The compiler-maintained index names several organizations and a competitive platform with Vyper review work. Read the individual scope before deciding whether that experience matches your need. A limited compiler review, a storage-layout assessment and an application audit are different evidence.

ChainSecurity's opened Curve Stablecoin report provides an application-level example. It lists Vyper compiler versions against the reviewed commits and identifies in-scope files. The report also states limitations, including that it did not review the economic soundness of the contracts. That boundary is relevant when a buyer is seeking an economic-design assessment in addition to code review.

Use the report to sharpen the request. Ask the candidate team for a Vyper engagement with comparable compiler, dependency and application complexity. Request an explanation of which tools they ran, what their tests asserted and how they handled known compiler advisories. A language name on a services page supplies less evidence than a scoped report.

A general Solidity report archive is a weak substitute for language-specific evidence. Request the Vyper source boundary, compiler assumptions and tool results from the actual engagement. The compiler index and Curve report provide different direct artifacts: one inventories compiler reviews, while the other identifies an application scope. Use that distinction when comparing proposals. A missing language keyword in another report would not establish that the firm lacks Vyper experience, just as a language keyword alone would not establish the coverage you need.

ChainSecurity's Curve Stablecoin assessment and Vyper's security policy establish the application and compiler evidence boundaries.

Use the audit-company analysis hub and Halborn analysis for provider context, then specify the required language evidence in the audit request. The chosen team should commit to the actual compiler and application scope.

The final acceptance record should make a simple comparison possible: the reviewed source and build settings produced the deployed artifact, and the report's conclusions apply to that configuration. Where that connection is not established, name the missing evidence. A compiler audit count cannot fill the gap.

For a compiler upgrade, preserve a comparison of the old and new build outputs alongside the regression results. Explain expected differences before attributing every bytecode change to an error. The review question is whether the new artifact preserves the required behavior under the intended execution rules, with any deliberate changes documented.

A language-specific test harness should also record which external dependencies it simulates. Instrumentation can make a failure easier to inspect while still leaving real token behavior or remote state outside the experiment. Keep those limits in the report so a reader can distinguish a reproduced application property from a broader deployment claim.

Frequently asked questions

Does a Python-looking syntax mean Vyper can be reviewed as ordinary Python?

No. The contract's language rules, compilation and EVM execution determine its behavior. Familiar syntax does not transfer Python runtime assumptions to a deployed contract.

Can a report covering a release candidate be treated as coverage of the final compiler?

Compare the reviewed candidate with the final release and identify changes outside the report. A shared version family does not establish that every later change received the same review.

Can verified source on an explorer establish the compiler executable used by CI?

Explorer verification and build-system provenance answer different questions. Retain the compiler distribution, checksum and build record used in the review, then compare its output with the verified deployment. A displayed version string alone does not establish the executable provenance.