Skip to content

v0.9.6

Latest

Choose a tag to compare

@pyk pyk released this 11 Sep 12:06
v0.9.6
351fc3b

Added

  • [solc] show_warning controls whether ripfuzz compile, ripfuzz test,
    ripfuzz max, and ripfuzz exec log solc warnings after compilation. It
    defaults to false, set it to true to show warnings.

  • ripfuzz compile <contract> compiles a contract through the shared solc
    pipeline and logs any warnings, so diagnostics that do not fail the build are
    visible without running test, max, or exec. Errors still fail the
    command with the compiler output. A cached compilation skips solc entirely.

  • ripfuzz test, ripfuzz max, and ripfuzz exec now log solc warnings after
    compilation, so diagnostics that do not fail the build stay visible in
    campaign output.

  • ripfuzz inspect storage-layout <contract> prints the storage layout of a
    contract as a markdown table with each variable's name, type, slot, offset,
    and byte size, read directly from the storageLayout of the compilation
    output. The inspector reuses the shared solc pipeline, so a cached
    compilation skips solc entirely.

  • ripfuzz inspect function-source <contract> <selector> prints the complete
    source of the function selected by its 4-byte selector together with every
    symbol it references: internal functions, modifiers, structs, enums, errors,
    events, state variables, and inherited declarations across the compilation
    unit. Each section renders with its natspec, resolving @inheritdoc
    directives from the inherited interface. The inspector reuses the shared solc
    pipeline, so a cached compilation skips solc entirely.

  • ripfuzz inspect external-functions <contract> prints a report of every
    externally callable function of a contract as a markdown table with its name,
    selector, mutability, modifiers, and source location. The report classifies
    functions into mutable, view, callback, and special sections. The inspector
    reuses the shared solc pipeline, so a cached compilation skips solc entirely.

  • Compiled solc outputs are now cached under a hash of the solc version and the
    standard JSON input at {out}/{hash}.json. Compilations with identical
    sources, settings, and compiler version reuse the cached output without
    running solc again.

  • ripfuzz fetch <name> <url> downloads and extracts a tar.gz dependency into
    .ripfuzz/dependencies/<name>, hashes the archive as a sha2-256 multihash,
    and records it under [dependencies] in ripfuzz.toml. Re-running fetch
    for a recorded dependency updates its URL and hash instead of erroring.

  • ripfuzz test, ripfuzz max, and ripfuzz exec now remap each dependency
    name onto its extracted sources, so
    import {InvariantTest} from "ripfuzz/std.sol" compiles without manual
    remappings. See docs/dependencies.md.

  • ripfuzz init now also creates a .gitignore with .ripfuzz and .env
    entries. An existing .gitignore gets only its missing entries appended.

  • ripfuzz test, ripfuzz max, and ripfuzz exec now deploy contracts that
    use Solidity libraries. Libraries with only internal functions are inlined by
    solc and need no deployment, while libraries with external functions are
    detected from the compilation link references, deployed first, and linked
    into the initcode, including nested library dependencies.

  • ripfuzz test now saves a fuzzing statistics report to
    .ripfuzz/stats/{unix-timestamp}-{id}.json at the end of each campaign. The
    report groups campaign metadata (harness, chain id, seed, budgets, totals)
    with per-handler and per-invariant entries carrying call counts, wall time
    min/max/avg, RPC cache hits/misses/wait, and reverts grouped by decoded kind
    and message.

  • ripfuzz test now names every per-run artifact after a single run id, so the
    log file, execution traces, coverage report, and fuzzing statistics of one
    campaign share their filename stem under .ripfuzz. The coverage report is
    saved per run as .ripfuzz/coverage/{run}.info instead of overwriting
    lcov.info, while the corpus keeps persisting across runs. and message.

  • ripfuzz test --stop-on-revert stops the campaign on the first reverted
    handler or invariant call and records it as a REVERT: finding that is
    shrunk and traced like a broken invariant. Without a value it stops on any
    revert except BrokenInvariantError reports, while
    --stop-on-revert 0xaa9a98df stops only on reverts starting with that 4-byte
    selector.

  • ripfuzz test --stop-on-panic stops the campaign on the first Solidity panic
    and records it as a PANIC: finding carrying the panic code, shrunk and
    traced like a broken invariant. Without a value it stops on any panic, while
    --stop-on-panic 0x01 stops only on that panic code, accepting decimal or
    0x-prefixed hex codes. selector.

  • ripfuzz test statistics now group reverts as a tagged kind enum where
    each kind holds only its own data: Error with selector and message, Panic
    with selector and code, CustomError with selector and the resolved error
    name, and BrokenInvariantError with selector and message.

Changed

  • Solc warnings are now hidden by default in ripfuzz compile, ripfuzz test,
    ripfuzz max, and ripfuzz exec output. Set [solc] show_warning = true in
    ripfuzz.toml to log them.

  • Broken invariants are now reported by reverting with the
    BrokenInvariantError custom error instead of the rvm.bail(Invariant)
    cheatcode: error BrokenInvariantError(string id, string description);.
    Harnesses no longer need the RVM interface or the cheatcode address for
    invariant reporting. The error must propagate to the top of the call, a
    revert caught with try/catch is treated as handled and is not reported.
    Solidity assert panics (Panic(0x01)) are not findings.

  • ripfuzz test and ripfuzz max now default --threads to the available CPU
    cores of the machine instead of a single thread.

  • --max-runs is renamed to --max-fuzz-runs and now defaults to 100,000
    sequences instead of 256. A new --max-shrink-runs flag decouples the
    shrinker budget from the fuzzing budget and defaults to 10,000 attempts.

  • Log lines that reference artifacts (corpus, coverage, trace, stats) now print
    paths relative to the project root instead of raw Path::display() output,
    so absolute writer paths render as e.g. .ripfuzz/stats/run.json.

  • ripfuzz test and ripfuzz max now log generating coverage report before
    building the coverage report, so large codebases no longer look stalled
    between the corpus save and the coverage save.

Fixed

  • Concurrent ripfuzz invocations compiling the identical input no longer fail
    with failed to write ./.ripfuzz/solc/<hash>.json. The compilation cache now
    writes each entry through a temporary file with a unique name, so parallel
    writers never rename the same temporary file twice.

  • ripfuzz init now installs stderr logging so command errors appear in the
    console. It writes no log file, keeping a fresh project free of .ripfuzz
    state.

  • A vm.prank caller that pays value in the pranked call no longer panics the
    fuzzer. The pranked address is now loaded into the journal before the frame
    runs, so a zero-balance sponsor reverts out-of-funds cleanly instead of
    hitting an unwrap on an unloaded account inside revm.