Skip to main content

pruf

Massive Proof of Concept engine for web3 bug hunters.

pruf has a fast Rust core built on the Foundry ecosystem (revm and alloy) with a thin Python API on top. The core executes EVM transactions in-process. The Python layer provides modular, composable, and serializable building blocks.

Example

Demonstrate an MEV sandwich attack on a Solidity project.

from pruf import Solidity
from pruf.blockchain import Ethereum, Base, Polygon

env = Ethereum() | Base() | Polygon()
env.from_config("https://example.com/project_audit_scopes.json")

victim_pre = (
    env.contracts.TokenA.approve(env.addresses.Marketplace, "12345e6")
    | env.contracts.Marketplace.swap(env.addresses.TokenA, env.addresses.TokenB, "12345e6").gas_price("1e6")
)

attacker_mid = env.contracts.Marketplace.swap(
    env.addresses.TokenA, env.addresses.TokenB, "12345e6"
).gas_price("1e18")

victim_post = env.contracts.Marketplace.swap(
    env.addresses.TokenB, env.addresses.TokenA, "12345e6"
)

poc = Solidity(env)
poc.watch(env.contracts.TokenA.balanceOf("0xabc"))
poc.watch(env.contracts.TokenA.balanceOf("0xwyz"), label="attacker balance")

# Watch a computed value: the lambda receives an evaluator that
# resolves a view Call to its decoded value.
poc.watch(
    lambda ev: ev(env.contracts.TokenA.balanceOf("0xabc"))
    + ev(env.contracts.TokenB.balanceOf("0xabc")),
    label="total balance",
)

poc.act(victim_pre, actor=poc.actor.Victim)
poc.act(attacker_mid, actor=poc.actor.Attacker)
poc.act(victim_post, actor=poc.actor.Victim)

poc.proof()
poc.export_as_json("myfile.json")

Generating scopes documents

The pruf-scopes command generates a scopes JSON from a Foundry or Hardhat project, so you never write deployment JSON by hand. The command reads the compiled artifacts and deployment records, then writes deploy steps with real constructor arguments.

From a Foundry project:

uv run pruf-scopes foundry \
  --out out \
  --broadcast broadcast \
  --out-file scopes.json

The broadcast can be a run-latest.json file or the broadcast directory. The tool picks the newest single-chain run.

From a Hardhat project (hardhat-deploy):

uv run pruf-scopes hardhat \
  --artifacts artifacts \
  --deployments deployments \
  --network sepolia \
  --out-file scopes.json

You can load the generated file with env.from_config("scopes.json") and run the PoC exactly as the example above shows.

Options:

  • --chain-name NAME: set the chain key in the generated document
  • --chain-id ID: set the chain id (default: from the artifacts)
  • --deployer ADDRESS: deployer used to compute engine addresses (default: the pruf FUNDER)

Output:

[STATE BEFORE ATTACK]
TokenA.balanceOf("0xabc") = 12345e6
attacker balance = 0
[STATE AFTER ATTACK]
TokenA.balanceOf("0xabc") = 0
attacker balance = 12345e6

transaction log:
  TokenA.approve -> ok
  TokenB.approve -> ok
  Marketplace.swap -> ok
  Marketplace.swap -> ok
  Marketplace.swap -> revert: insufficient balance

reloaded from myfile.json, proof again:
[STATE BEFORE ATTACK]
TokenA.balanceOf("0xabc") = 12345e6
attacker balance = 0
[STATE AFTER ATTACK]
TokenA.balanceOf("0xabc") = 0
attacker balance = 12345e6

Development

Requirements:

  • Python 3.13 or newer
  • Rust 1.91 or newer (for the core crate)
  • uv

Build the native core and install the package in editable mode:

uv sync
uv run maturin develop

Run the test suite:

uv run pytest

Run the demo:

uv run python examples/mev_sandwich.py

Run the Sherlock OPoC example (Metric OMM Protocol audit competition):

uv run python examples/sherlock_metric_opoc.py

Layout

  • crates/pruf-core: the Rust EVM execution core (revm + PyO3)
  • src/pruf: the Python API (includes pruf.sherlock, pre-built audit competition environments)
  • fixtures: Solidity demo contracts and the sample scopes document
  • examples: runnable demos (MEV sandwich, Sherlock Metric OPoC)
  • tests: the pytest suite

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pruf-0.2.0.tar.gz (51.4 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

pruf-0.2.0-cp313-abi3-manylinux_2_34_x86_64.whl (2.1 MB view details)

Uploaded CPython 3.13+manylinux: glibc 2.34+ x86-64

pruf-0.2.0-cp313-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (2.1 MB view details)

Uploaded CPython 3.13+manylinux: glibc 2.17+ ARM64

File details

Details for the file pruf-0.2.0.tar.gz.

File metadata

  • Download URL: pruf-0.2.0.tar.gz
  • Upload date:
  • Size: 51.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for pruf-0.2.0.tar.gz
Algorithm Hash digest
SHA256 2d2be88579895f53982aabe04ff3382f3bf9d434b4d4d18d3b037ad748155d5c
MD5 dab46d9917d5dae62f2c8367827ae9de
BLAKE2b-256 b041f325dc3b7691b61e7404d4726e62db1d0ea74d8c487c54ab2da57a8dea31

See more details on using hashes here.

Provenance

The following attestation bundles were made for pruf-0.2.0.tar.gz:

Publisher: release.yml on HanzCEO/pruf

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pruf-0.2.0-cp313-abi3-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for pruf-0.2.0-cp313-abi3-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 776ef6b5a9352e612017c023b4fbb88955307989b381d7b5394415ee9b3d3292
MD5 f63b1d46d940953bffd469166eb42ae5
BLAKE2b-256 0c96a437476b729c541456afe9d8de547a8df81c916bfc85c3e7efcc970f3085

See more details on using hashes here.

Provenance

The following attestation bundles were made for pruf-0.2.0-cp313-abi3-manylinux_2_34_x86_64.whl:

Publisher: release.yml on HanzCEO/pruf

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pruf-0.2.0-cp313-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for pruf-0.2.0-cp313-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 5c40a2d37a5baa5cadd4f04e8ccce26c51b715fb17354348947cc614f4774326
MD5 f3299714aaeaf9d414d0566e9568b9ab
BLAKE2b-256 86b06ec47f11497331ad1c92be27968f6ca5e38e2324fbcea4ef58a40fd99183

See more details on using hashes here.

Provenance

The following attestation bundles were made for pruf-0.2.0-cp313-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release.yml on HanzCEO/pruf

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.2.0 This release

3 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page