Logo
New RPC users get 35% off their first monthView the offer
OnFinality Learn
Integration & Development11 min read

Cyfrin Security Tooling: A Practical Workflow for Smart Contract Audits

A reproducible workflow for using Cyfrin's open-source security tools, audit resources, and education platform to prepare a smart contract codebase for review.

TL;DR

Cyfrin is a blockchain security company whose public footprint spans smart contract audits, the Aderyn static analyzer, the Solodit audit-report aggregator, the CodeHawks competitive audit platform, and the Updraft education platform. This article treats those products as parts of one reproducible pre-audit workflow rather than as a brand overview. You will set up static analysis, map findings to a checklist, cross-reference historical reports, and verify deployed behavior against a live chain through an RPC endpoint. The goal is a codebase that reaches a human auditor with fewer trivial findings and better documentation.

Scope and the mental model behind a Cyfrin-style review

Cyfrin's public materials describe a security stack built around four layers: manual smart contract audits, automated static analysis through Aderyn, an aggregated findings database through Solodit, and developer education through Updraft and CodeHawks. The useful way to think about this stack is as a funnel. Automated tooling and historical findings remove low-severity noise; competitive audits and education build reviewer intuition; manual review spends expensive human attention on logic, economics, and access control.

This article covers the automated and reference layers you can run yourself before engaging any auditor. It does not claim to reproduce a paid Cyfrin audit, and it does not assert which networks or services Cyfrin supports beyond what its public repositories and site state. Where a concrete RPC endpoint choice is needed, use the RPC endpoints guide or ask RPC Assistant for a provider recommendation rather than hardcoding an endpoint from this page.

  • Documented behavior: Aderyn is a Solidity static analyzer written in Rust and published under GPL-3.0 in the Cyfrin GitHub organization.
  • Documented behavior: Solodit aggregates smart contract audit findings; CodeHawks hosts competitive audits; Updraft hosts developer and security courses.
  • Recommendation: run static analysis and checklist review before requesting a quote, because it reduces the surface a human reviewer must triage.

Prerequisites and assumptions

The workflow assumes a Solidity project using Hardhat or Foundry with a lockfile committed, a Node.js or Rust toolchain available locally, and read access to a public or private RPC endpoint for the target network. You need repository write access to add CI jobs and a place to store generated reports as build artifacts.

You do not need a Cyfrin account to run Aderyn or to read public audit reports. Paid audit engagements, certification tracks, and some platform features are separate commercial offerings; treat their availability as something to confirm directly with the vendor rather than assume from this article.

Installing and running Aderyn static analysis

Aderyn is distributed as a Rust binary and can be installed through Cargo or a release binary. Running it against a compiled project produces a Markdown or JSON report of detector hits. The first run is usually noisy; the value comes from triaging each detector class once and then encoding that triage as a baseline so later runs surface only new findings.

The command below is a runnable starting point. Replace the project path with your repository root and keep the report outside the source tree so it does not get committed accidentally.

cargo install aderyn
cd /path/to/your-solidity-project
aderyn . --output report.md
# JSON output for CI ingestion
aderyn . --output report.json --output-format json
# Fail the build only on high-severity detectors (check --help for exact flags in your version)
aderyn . --output report.json --output-format json --fail-on high

Mapping findings to an audit checklist

Cyfrin publishes an aggregated audit checklist repository that groups common vulnerability classes by category, such as access control, arithmetic, external calls, and oracle usage. Rather than reading it top to bottom, map each Aderyn detector hit to a checklist entry and record whether the finding is a true positive, a false positive, or accepted risk with a written justification.

This mapping step is where most of the value is created. It converts a raw tool report into an audit-ready document that a human reviewer can skim. Store the mapping in the repository, for example as security/triage.md, so it survives team changes.

  • True positive: fix the code and add a regression test that fails before the fix.
  • False positive: document the invariant that makes the detector inapplicable.
  • Accepted risk: record the owner, rationale, and expiry date for the acceptance.

Cross-referencing historical findings with Solodit

Solodit aggregates findings from many public audit reports, which makes it useful for answering a narrow question: has this exact pattern been exploited or flagged before, and how was it remediated? Search by protocol type and by the specific function shape rather than by keyword alone, because generic terms return too much noise.

Treat Solodit results as prior art, not as proof that your code is safe. A finding that appears in another protocol's report may be inapplicable to your architecture, and absence of a matching finding says nothing about your code. The correct output of this step is a short list of candidate issues to verify manually, each linked to its source report.

Verifying deployed behavior against a live chain

Static analysis cannot see deployed state. Before an audit, confirm that the bytecode you analyzed matches what is deployed and that privileged roles are configured as documented. A small script that reads role assignments and key parameters through an RPC endpoint catches configuration drift that no source-level tool will find.

The example below uses ethers.js and reads a role constant and an owner address. Replace RPC_URL, CONTRACT_ADDRESS, and the ABI with values for your deployment. For provider selection across networks, see multi-chain RPC endpoints and the API service overview.

import { ethers } from "ethers";

const provider = new ethers.JsonRpcProvider(process.env.RPC_URL);
const address = process.env.CONTRACT_ADDRESS;
const abi = [
  "function owner() view returns (address)",
  "function hasRole(bytes32 role, address account) view returns (bool)",
  "function DEFAULT_ADMIN_ROLE() view returns (bytes32)"
];

const contract = new ethers.Contract(address, abi, provider);
const [owner, adminRole] = await Promise.all([
  contract.owner(),
  contract.DEFAULT_ADMIN_ROLE()
]);
const ownerIsAdmin = await contract.hasRole(adminRole, owner);

console.log({ address, owner, ownerIsAdmin });
if (!ownerIsAdmin) {
  console.warn("Owner does not hold DEFAULT_ADMIN_ROLE; confirm this is intentional.");
}

Expected verification results and how to record them

A successful pre-audit pass produces four artifacts: an Aderyn report, a triage document with every detector class resolved, a list of Solodit cross-references with links, and a deployment-state snapshot from the RPC script. Record the commit hash, tool versions, and block number alongside each artifact so the results are reproducible.

Use a results table like the one below in your repository. Do not copy numbers from another project; fill each cell from your own run. The table is a template, not a benchmark.

  • | Artifact | Command or source | Commit / block | Reviewer | Status |
  • | Aderyn report | aderyn . --output report.json | <commit> | <name> | <open/closed> |
  • | Triage document | security/triage.md | <commit> | <name> | <open/closed> |
  • | Solodit cross-refs | manual search log | n/a | <name> | <open/closed> |
  • | Deployment snapshot | RPC script output | <block> | <name> | <open/closed> |

Adding the workflow to CI

The most common failure mode is a one-time analysis that is never rerun. Wire Aderyn into CI so every pull request produces a fresh report, and diff it against the baseline from the default branch. A simple approach is to upload the JSON report as an artifact and run a small script that compares detector counts by severity.

Keep the CI job non-blocking at first, then promote specific detectors to blocking once the team has triaged them. Blocking on the full detector set on day one usually causes developers to bypass the check entirely.

# .github/workflows/security.yml (excerpt)
name: security
on: [pull_request]
jobs:
  aderyn:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
      - run: cargo install aderyn
      - run: aderyn . --output report.json --output-format json
      - uses: actions/upload-artifact@v4
        with:
          name: aderyn-report
          path: report.json

Troubleshooting common failures

Static analyzers fail in predictable ways. Most false negatives come from incomplete compilation, and most false positives come from detectors that cannot see cross-contract invariants. Address compilation first, because a project that does not build cleanly will produce a misleadingly small report.

RPC scripts fail for a different set of reasons: rate limits, wrong chain IDs, and ABI mismatches after an upgrade. Log the chain ID returned by the provider and compare it to the expected value before trusting any read result.

  • Empty or tiny Aderyn report: confirm the project compiles and that the path argument points at the source root, not the repository root.
  • Detector hits on generated or vendored code: exclude those paths explicitly rather than ignoring the whole detector.
  • RPC script returns null: verify the ABI matches the deployed implementation, especially behind proxies.
  • Intermittent RPC timeouts: move to a dedicated endpoint; see dedicated nodes and RPC pricing.

Limitations and tradeoffs

Automated tooling covers a minority of real exploit classes. Logic errors, economic manipulation, oracle design flaws, and governance attacks generally require human review and often protocol-specific simulation. Aderyn and similar analyzers are best understood as a filter that protects auditor attention, not as a substitute for it.

There is also a maintenance cost. Detector baselines drift as tools update, checklists go stale, and CI jobs accumulate exceptions. Budget time each quarter to re-triage the baseline and remove suppressions that no longer apply. If your team cannot sustain that cadence, a narrower workflow that actually runs is better than a comprehensive one that is abandoned.

Next steps toward an audit engagement

Once the four artifacts exist and CI is green, you have a defensible starting point for a paid review or a competitive audit on CodeHawks. Prepare a short architecture note covering trust assumptions, privileged roles, upgrade paths, and external dependencies, because those are the areas where manual review spends the most time.

For teams also operating infrastructure, verify that the RPC layer used for deployment and monitoring is stable before the audit window; an unreliable endpoint during a live review wastes reviewer time. Compare options through OnFinality networks and the RPC endpoints guide, and use RPC Assistant when you need a direct provider recommendation for a specific chain.

Never Worry about Infrastructure Again

OnFinality takes away the heavy lifting of DevOps so you can build smarter and faster.

Get Started