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 (includespruf.sherlock, pre-built audit competition environments)fixtures: Solidity demo contracts and the sample scopes documentexamples: 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
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2d2be88579895f53982aabe04ff3382f3bf9d434b4d4d18d3b037ad748155d5c
|
|
| MD5 |
dab46d9917d5dae62f2c8367827ae9de
|
|
| BLAKE2b-256 |
b041f325dc3b7691b61e7404d4726e62db1d0ea74d8c487c54ab2da57a8dea31
|
Provenance
The following attestation bundles were made for pruf-0.2.0.tar.gz:
Publisher:
release.yml on HanzCEO/pruf
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pruf-0.2.0.tar.gz -
Subject digest:
2d2be88579895f53982aabe04ff3382f3bf9d434b4d4d18d3b037ad748155d5c - Sigstore transparency entry: 2346326434
- Sigstore integration time:
-
Permalink:
HanzCEO/pruf@244e21397f3831a5c1853eee34c07c785bced066 -
Branch / Tag:
refs/tags/0.2.0 - Owner: https://github.com/HanzCEO
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@244e21397f3831a5c1853eee34c07c785bced066 -
Trigger Event:
release
-
Statement type:
File details
Details for the file pruf-0.2.0-cp313-abi3-manylinux_2_34_x86_64.whl.
File metadata
- Download URL: pruf-0.2.0-cp313-abi3-manylinux_2_34_x86_64.whl
- Upload date:
- Size: 2.1 MB
- Tags: CPython 3.13+, manylinux: glibc 2.34+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
776ef6b5a9352e612017c023b4fbb88955307989b381d7b5394415ee9b3d3292
|
|
| MD5 |
f63b1d46d940953bffd469166eb42ae5
|
|
| BLAKE2b-256 |
0c96a437476b729c541456afe9d8de547a8df81c916bfc85c3e7efcc970f3085
|
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
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pruf-0.2.0-cp313-abi3-manylinux_2_34_x86_64.whl -
Subject digest:
776ef6b5a9352e612017c023b4fbb88955307989b381d7b5394415ee9b3d3292 - Sigstore transparency entry: 2346327223
- Sigstore integration time:
-
Permalink:
HanzCEO/pruf@244e21397f3831a5c1853eee34c07c785bced066 -
Branch / Tag:
refs/tags/0.2.0 - Owner: https://github.com/HanzCEO
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@244e21397f3831a5c1853eee34c07c785bced066 -
Trigger Event:
release
-
Statement type:
File details
Details for the file pruf-0.2.0-cp313-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: pruf-0.2.0-cp313-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 2.1 MB
- Tags: CPython 3.13+, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5c40a2d37a5baa5cadd4f04e8ccce26c51b715fb17354348947cc614f4774326
|
|
| MD5 |
f3299714aaeaf9d414d0566e9568b9ab
|
|
| BLAKE2b-256 |
86b06ec47f11497331ad1c92be27968f6ca5e38e2324fbcea4ef58a40fd99183
|
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
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pruf-0.2.0-cp313-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl -
Subject digest:
5c40a2d37a5baa5cadd4f04e8ccce26c51b715fb17354348947cc614f4774326 - Sigstore transparency entry: 2346326833
- Sigstore integration time:
-
Permalink:
HanzCEO/pruf@244e21397f3831a5c1853eee34c07c785bced066 -
Branch / Tag:
refs/tags/0.2.0 - Owner: https://github.com/HanzCEO
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@244e21397f3831a5c1853eee34c07c785bced066 -
Trigger Event:
release
-
Statement type: