Skip to content

SOME ONE IS STEALING MY CRYPTO - #1

Open
caraabearzz wants to merge 4039 commits into
caraabearzz:masterfrom
foundry-rs:master
Open

caraabearzz wants to merge 4039 commits into
caraabearzz:masterfrom
foundry-rs:master

Conversation

@caraabearzz

@caraabearzz caraabearzz commented Jul 22, 2025 •

Copy link
Copy Markdown
Owner

Motivation

Solution

PR Checklist

  • Added Tests
  • Added Documentation
  • Breaking changes

@caraabearzz caraabearzz left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this was really good feedback. Thank you

figtracer and others added 29 commits September 30, 2026 11:10
* fix(cheatcodes): read symlink targets correctly

Keep the canonical filesystem permission check, but read the original rooted link path instead of its resolved target. Extend the existing Unix symlink permission integration test to cover relative and absolute readLink inputs without changing other filesystem operations.

* docs(cheatcodes): clarify link path validation

Explain why readLink validates the canonical target while operating on the link pathname. Remove the obsolete changelog fragment.
* fix(forge): honor inspect compiler selectors

Use the resolved project compiler version when exporting standard JSON for an explicit --use selector. Parsing the original selector as semver rejects supported aliases and executable paths after compilation succeeds. Preserve no-selector output and extend the existing CLI regression.

* chore: remove obsolete changelog fragment

* fix(forge): sanitize configured compiler exports

Use the resolved compiler or selected artifact metadata when producing
standard JSON, including when --use is absent. Otherwise older compilers
reject unsupported settings in exports from configured projects.

Extend the existing regression to compare a configured compiler with
its explicit selector; preserve the normal output snapshot.
* fix(evm): prevent OP fork fee panics

Preserve disabled fee charging when selecting a fork so synthetic execution does not enter OP fee reimbursement with an empty fee context. Restrict inferred Optimism execution to OP Stack fork sources and explain how scripts can select the appropriate EVM.

Add regression coverage for fork compatibility and fee charging preservation.

* test(anvil): expect non-OP reset rejection

Align inferred Optimism fork reset coverage with the OP state-source requirement. Verify rejected resets preserve the original fork and leave the node able to mine.
Skip dynamic linking during ABI-only test discovery so its cache no longer depends on the changing compiler job. Keep preprocessing enabled for bytecode compilation and cover edits to selected and unselected tests.

On Solady, test edits compile 11 ABI sources instead of 208; matched profiling benchmarks improve from 1.932 s to 0.596 s. Bytecode artifacts remain identical.
Import AnvilBlockExecutor whenever the OP-stack receipt module is enabled. Base-only builds also compile its implementation, so gating the import on Optimism leaves the type unavailable.
Canonical BAL writes may differ from prefix execution under explicit execution rules. Fall back to replay and cover both CLI and configured hardfork overrides.
`chisel view` now returns before config loading, so it no longer
discovers the fork endpoint or looks up Solc just to print cached
source. The view test no longer passes `--use`, which used to hide
that dependency.

Session serialization now uses the derived serde impl, with getters
that strip credentials, instead of a hand-written field list. The
dispatcher now keeps only the invocation's RPC credentials and
transport settings instead of a whole `SessionSourceConfig`.

Follow-up to #17143.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* fix(fmt): make the size estimate describe the printed form

`estimate_size` measures the source text while the printer normalizes it, so a
layout decision sitting near the line limit is taken from a width the printer
will never produce, and then flips on the second pass once the source has been
normalized.

Three normalizations account for the cases found so far. The spacing just
inside a brace pair follows `bracket_spacing`, the integer types are respelled
according to `int_types`, and `bracket_spacing` was also being charged for
parentheses and square brackets at a line boundary, which the printer does not
space. Measure all three as they will be printed.

* fix(fmt): scope normalized size estimates

Limit delimiter width normalization to call arguments and measure integer spelling from parsed types. Ignore braces in literals and comments so unrelated text cannot affect layout decisions.

Keep the three 120-column idempotency reproductions stable without changing settled output in the pinned 20-project corpus.

* fix(fmt): count tabs in brace spacing estimates

Treat a tab adjacent to a brace as existing whitespace when estimating the printed width. This keeps tabbed call arguments stable on the first formatting pass.

Add a regression case for the 120-column layout decision.

* test(fmt): remove redundant default snapshots

The parent formatter already handles these three cases at 80 columns. Keep their 120-column snapshots, which reproduce the idempotency failures and assert stable output.

---------

Co-authored-by: Mablr <59505383+mablr@users.noreply.github.com>
Exercise salted deployCode with isolation and nested constructor
activity, verify one-shot broadcast cleanup after failed deployments,
and cover CREATE2 routing in Tempo batch mode.
chore: bump forge-std version used for tests

Co-authored-by: mablr <59505383+mablr@users.noreply.github.com>
* fix(cli): warn on dotenv loading errors

Report dotenv loading failures instead of silently discarding them. Preserve stop-on-error behavior and omit malformed source lines from diagnostics because they can contain secrets. Add a CLI regression snapshot for the warning.

* fix: init global shell

* fix(cli): honor quiet for dotenv warnings

Return dotenv diagnostics from startup and emit them after argument parsing configures the global shell. Keep dotenv loading before parsing and cover quiet output in the Cast regression test.
chore: bump revm-inspectors to 0.44.1

Pick up fixes for empty code hashes and parity trace output, including deleted-account storage diffs, vmTrace alignment, and reverted creation addresses. Keep the existing dependency graph otherwise unchanged.
Allow the platform executable suffix in the unlocked remote signer conflict diagnostic. Windows reports forge.exe while Unix reports forge, causing an otherwise correct clap conflict error to fail the snapshot.
* fix(cast): list Turnkey signers in `cast wallet list --turnkey`

`--turnkey` was passed to the wallet options but its signers were never
listed, and local keystore accounts were printed instead because the
local-accounts condition did not include it.

Co-authored-by: cui <1579517+cuiweixie@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(cast): cover Turnkey wallet listing

Gate HOME-dependent coverage on non-Windows targets and replace wallet creation with a minimal keystore fixture. Clear inherited credentials and check missing-credential diagnostics, plus configured Turnkey addresses in text and JSON output.

---------

Co-authored-by: cui <1579517+cuiweixie@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Gustavo Figueiredo <me@figtracer.com>
Distinguish invalid jumps and static-context violations from ordinary REVERT outcomes so call assumptions preserve concrete execution semantics. Keep invalid conditional-jump fallthrough paths intact.

Refs OSS-885.
Co-authored-by: DaniPopes <57450786+DaniPopes@users.noreply.github.com>
Co-authored-by: Derek <256792747+decofe@users.noreply.github.com>
* chore(bench): add offline Jev plan experiment

Keep policy planning outside the local invariant engine and compare matched campaign budgets through scfuzzbench. Record synthetic-only plumbing evidence without attributing discovery gains to Jev.

AI-assisted with Codex.

* test(bench): refresh Jev campaign evidence

Rebuild Forge and foundry-scfuzzbench from the PR commit, rerun all 30 stateful trials, and replace the stale campaign tables and binary provenance. The synthetic weighted policy still shows no discovery gain over baseline.

* test(bench): record live Jev decisions

Capture two paid Jev 1.13 choices against the pinned public Origin Dollar harness. Both preserve the existing campaign configuration, so the evidence remains explicitly negative rather than attributing a discovery gain to the planner.\n\nAI-assisted with Codex.

* docs(bench): clarify live schedule evidence

Describe the post-response deterministic schedule accurately without calling it pre-registered.\n\nAI-assisted with Codex.

* test(bench): record Jev frontier screen

* feat(fuzz): bootstrap protocol lifecycles

Derive bounded lending and vault call sequences from targeted ABIs and interleave at most 256 sequences before returning entirely to the existing random invariant generator. The feature is opt-in and leaves unrecognized handlers on the default path.

In matched 60-second, three-seed campaigns, Aave lifecycle scheduling raised shouldNotBecomeLiquidatable from 1/3 to 3/3 seeds and totalBorrowedLessThanSupplied from 0/3 to 2/3. Superform's mint/redeem symmetry assertion rose from 2/3 to 3/3 with neutral call throughput.

* feat(fuzz): allow declared call sequences

Let invariant harnesses declare bounded cross-contract call sequences without relying on protocol-specific ABI names. Declared sequences run before and alongside inferred lifecycle scenarios, using the existing calldata and dictionary generators.

* refactor(fuzz): narrow call sequence seeding

Remove ABI-name lifecycle inference and make explicit harness declarations finite run-local prefixes. Reuse normal sender and calldata generation, then let ordinary coverage retention decide whether completed prefixes survive.

* fix(fuzz): preserve timed corpus seeds

Preserve forward timestamp and block-number changes when converting sibling zero-input test traces into invariant corpus entries. Skip traces whose environment changes cannot be represented exactly, and remove the unproven declared-call-sequence API from this draft.

* fix(fuzz): reject restored trace seeds

Snapshot restoration can undo both target calls and environment changes. Reject sibling-test traces containing current or deprecated state-restoration cheatcodes because the observed trace cannot reconstruct the restored snapshot exactly.

* fix(fuzz): use effective seed block
* fix(forge): preserve filtered test diagnostics

Retain test discovery metadata so filtered compilation does not
misreport an existing test project as empty. Ignore contracts the runner
cannot deploy.

Use retained candidates for unmatched-filter suggestions and cover test
and contract filters with dynamic linking enabled and disabled.

* refactor(forge): simplify unmatched test warnings

Resolve diagnostic candidates from cached ABI discovery only when no tests match, instead of carrying unmatched-test state through compilation and execution. Reuse the runner matcher and borrow candidate names.

Cover filtered diagnostics with caching enabled and disabled.

* fix(forge): satisfy diagnostic branch lint

Use the positive has_tests condition first to satisfy Clippy without changing filtered-test diagnostics.

---------

Co-authored-by: Gustavo Figueiredo <me@figtracer.com>
Require a unique canonical ABI suffix for dynamic constructor arguments instead of selecting the shortest match. Nested ABI-encoded bytes can otherwise produce a valid but incorrect split for constructor-args and creation-code.
Quiet mode skipped report handling and its contract-size checks, allowing
oversized builds to exit successfully. Keep requested validation active
while suppressing report output, and extend the existing CLI regression.
* fix(traces): decode calldata with a trailing suffix

Routers and wallets append tracking or attribution bytes to ABI-encoded
calldata, e.g. 1inch AggregationRouterV6 `swap` and Universal Router
`execute`. The ABI shape heuristic rejected such calldata because its
length isn't word-aligned, so the selectors were never identified and
`cast run` rendered raw hex.

Calldata with a non-zero sub-word suffix is now treated as ABI-encoded
when its first argument word is left-padded, which packed calldata rarely
is. It is only decoded with a function whose exact ABI encoding matches
the word-aligned prefix, so packed calldata isn't shown as a function with
fewer inputs, and cheatcode calls still always redact their inputs.

* fix(traces): strip ERC-8021 attribution suffixes

ERC-8021 attribution suffixes end in a fixed 16-byte marker and encode
their own length, so they can be removed exactly instead of relying on
the sub-word suffix heuristic. In 40 recent Base blocks, 255 of 9087
transactions carried one, and only 84 of them decoded with the heuristic
alone: schema 2 and multi-code suffixes are 32 bytes or longer, and calls
whose first argument isn't left-padded (e.g. bytes16) fail the first-word
check.

The suffix is now removed before the ABI shape checks, and any
remaining sub-word tag (e.g. Universal Router tracking bytes before the
ERC-8021 suffix) is still handled by the existing suffix check.

* fix(traces): select suffixed functions for unknown selectors

The unknown-selector branch for known contracts without a fallback
decoded with the first function for the selector before the exact-prefix
check ran, so suffixed packed calldata was still shown as a function with
fewer inputs. Run function selection before that branch as well.

* feat(cast): print ERC-8021 attribution codes (#17178)

* feat(cast): print ERC-8021 attribution codes

`cast run` and `cast call --trace` now print the codes of ERC-8021
attribution suffixes found in the trace after the gas used. The suffix
parsing moves into a `foundry_evm_traces::erc8021` module, which the
decoder also uses to strip the suffix.

* chore: add ciborium to foundry-evm-traces lockfile entry
* feat(tempo): label OUSD token

Co-authored-by: Derek Cofausper <256792747+decofe@users.noreply.github.com>

* Update crates/common/src/tempo/mod.rs

* Update crates/common/src/tempo/mod.rs

---------

Co-authored-by: Matthias Seitz <19890894+mattsse@users.noreply.github.com>
Co-authored-by: figtracer <me@figtracer.com>
Cached artifacts do not retain compiler diagnostics, so a cache populated without a strict deny policy can bypass a later warning gate. Disable compilation caching when the deny policy includes warnings and cover build, test, and configuration-based gates.
* fix(fuzz): skip history-changing trace seeds

Reject test-derived seeds with forward rolls on Prague and later forks because block-number deltas cannot replay EIP-2935 history writes. Preserve pre-Prague and no-op rolls, and cover the history-dependent source-test mismatch.

* fix(fuzz): honor trace seed EVM override

Use the persisted setup EVM version when deciding whether a trace seed
contains unreplayable Prague block history changes. Reject traces that
change versions during the test because corpus replay cannot preserve
those transitions.

---------

Co-authored-by: Mablr <59505383+mablr@users.noreply.github.com>
Co-authored-by: jenpaff <5339211+jenpaff@users.noreply.github.com>
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
figtracer and others added 30 commits October 8, 2026 21:37
The mutation runner copied `--mutation-timeout` into `fuzz.timeout` and
`invariant.timeout` for each mutant. A fuzz or invariant `timeout` turns a
run-limited campaign into a time-based one, so a surviving mutant ran its
campaign for the full budget and was reported as timed out.

Stop the mutant's test run at the per-mutant deadline through the runner's
early-exit signal instead, as Ctrl+C does. Run limits and user-configured
timeouts keep their meaning, and a timed-out worker still stops. A result
that arrives after the deadline is reported as timed out, because it can
come from a stopped run.
* fix(cast): use --proxy for local storage layouts

`cast storage` matched local artifacts against the code at the queried
address and only consulted `--proxy` when falling back to Etherscan.
When the proxy itself compiles in the local project, its own (usually
empty) layout was printed. When only the implementation compiles
locally, the lookup went to Etherscan and failed on chains without an
explorer.

Resolve `--proxy` before the local lookup and match against the code at
that address, while still reading the values from the queried address.

* fix(cast): match immutables in local storage

Immutables are zero in an artifact's deployed bytecode and only filled
in at deployment, so a deployed contract with immutables never matched
its local artifact exactly. `cast storage` then fell back to Etherscan,
which fails on local chains.

Ignore the bytes covered by the artifact's immutable references when
comparing. Everything else, including the metadata hash, still has to
match exactly.

* fix(cast): reject ambiguous local storage layouts

The local lookup took the first artifact whose deployed bytecode
matched. When two contracts compile to the same code, for example
without a metadata hash, `cast storage` printed whichever came first.

Collect every match on both compile paths and fail with an error that
names the contracts when more than one contract matches.

* fix(cast): require metadata hash to skip immutables

Ignoring the bytes of immutables is only safe when the code ends in a
metadata hash, which commits to the sources and compiler settings.
Without one, a different contract that shares every other byte would
match.

Compare the code exactly when the artifact has no metadata hash.

* fix(cast): reject a --proxy address without code

When the `--proxy` address had no code at the queried block, `cast
storage` skipped the local lookup and fell back to Etherscan, so the
layout could come from a contract that did not exist at that block.

Fail instead, as for a queried address without code. The test reads a
clone through `--proxy` before its implementation is deployed, then at
two later blocks.

* test(cast): cover local storage JSON and immutables

Check the `--json` output through `--proxy`, and a contract deployed on
anvil whose constructor sets an immutable.

---------

Co-authored-by: Mablr <59505383+mablr@users.noreply.github.com>
Accept Celo CIP-64 envelopes in Anvil while preserving their signed
identity and feeCurrency through filling, submission, and RPC responses.
Project execution onto EIP-1559 native fee accounting as a temporary
compatibility mode, with the limitation documented and warned at startup.

Reject CIP-64 outside Celo mode, including reorg, state import, and fork
replay paths. Keep authoritative hashes for impersonated transactions.
Share item rendering and source/page path handling, remove redundant NatSpec state, and reuse Solar metadata. Separate rendering from output ownership updates while preserving generated output and failure behavior.
Reuse fixture setup and group related variable and overload cases while preserving their scenarios. Strengthen output assertions and cover generated-site ownership, external-library links, and deployment eligibility.
A prank created with `delegateCall = true` was applied to delegate calls
but never marked as used, so overriding an ongoing delegate `startPrank`
whose only use was a delegate call failed with "cannot overwrite a prank
until it is applied at least once". Mark it as used in the delegate
branch, like calls, creates and `deploy_code` already do. This also
aligns revm with evm2.
Canonicalize the external library fixture with dunce so verbatim Windows prefixes do not inject backslash escapes into Solidity import literals. Require a clean diagnostic stream when generating the documentation.

Co-authored-by: grandizzy <38490174+grandizzy@users.noreply.github.com>
Co-authored-by: DaniPopes <57450786+DaniPopes@users.noreply.github.com>
* fix(traces): keep external lookups on the traced chain

An `[etherscan]` alias set through `etherscan_api_key` or `eth_rpc_url`
could override the chain being traced, so Etherscan and Sourcify were
queried on the alias's chain after forking another chain. Ignore an
alias pinned to a different chain than the traced one, and never let
the resolved config replace the traced chain used for Sourcify.

* test(traces): assert explorer targets the traced chain
* fix(forge): reset library deployer nonce on forks

Nonce-linked libraries are linked from LIBRARY_DEPLOYER nonce 0, but test
setup deployed them from the fork-reported nonce. Reset the account nonce
before deploying so libraries land at their linked addresses.

* fix(forge): skip deployer nonce reset without libraries
Replace concrete associated-type projections and fixed-network aliases with their underlying types. Keep generic projections and aliases whose expansion would increase complexity.
Split environment traits and RPC transaction conversion into focused modules while retaining their public re-exports. Deduplicate common context checks and RPC fixture setup, retain existing test cases, and assert restoration after clone/set round trips.
Resolve an ambiguous delegated CREATE submission while it is still
pending, then interrupt receipt waiting after the resolved hash is
checkpointed. Verify that plain resume reconciles the mined transaction
without another submission.
#17504 added base-common-consensus as an optional normal dependency of
forge behind the `base` feature, but only the base CLI integration test
uses it. Since forge warns on unused_crate_dependencies, stable builds
with `base` now report the crate as unused. Move it to dev-dependencies.
Check process status before script outcome text, reuse projects across text and JSON failure cases, and share manual gas-limit setup and recovery artifact lookup while retaining scenario-specific assertions.
Read RPC metadata from the original transactions instead of normalizing an unused clone. Aggregate setup execution results once for both successful calls and execution errors.
Restrict submission to prepared transaction bytes or delegated requests, removing unreachable signing and retry paths while preserving checkpoint ordering and exact payload replay. Share authoritative recovery loading between single-chain and multi-chain sequences without changing legacy import or lock behavior.
* fix(config): limit absolute remapping aliases

Only add absolute aliases for relative contexts outside the project
root. Internal source units are root-relative, so their aliases only
leak checkout paths into metadata and make bytecode depend on the build
directory.

Preserve external context resolution and alias ordering, and cover
bytecode reproducibility across project roots.

* test(config): keep remapping fixture portable

Use a context without a trailing separator so the metadata assertion does not depend on Windows context formatting. Keep the absolute-alias and bytecode reproducibility checks intact.
Execute synchronous script simulation directly in transaction order, retaining outcomes for the existing reporting phase. Remove shared runner locks and decoder ownership wrappers, and extract pre-broadcast gas estimate printing from transaction grouping without changing network-specific simulation or fee policy.
* fix(forge): reject overflowing snapshot values

Signed-off-by: fmterrors <fmterrors@outlook.com>

* fix(forge): contextualize snapshot errors

Report the snapshot path and line for invalid numeric values. Cover
every numeric field and verify both overflow rejection and maximum
accepted values.

---------

Signed-off-by: fmterrors <fmterrors@outlook.com>
Co-authored-by: Mablr <59505383+mablr@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.