Skip to content

fix(cheatcodes): charge deployCode creation gas to caller - #17732

Merged
0xKarl98 merged 2 commits into
masterfrom
steven/deploycode-gas-dynamic-linking
Oct 22, 2026
Merged

0xKarl98 merged 2 commits into
masterfrom
steven/deploycode-gas-dynamic-linking

Conversation

@stevencartavia

Copy link
Copy Markdown
Member

With dynamic test linking, which is on by default, new expressions in tests are rewritten to vm.deployCode. Like every cheatcode, deployCode returned all of its gas to the caller, so the creation was left out of test gas, forge snapshot, gas snapshot cheatcodes, and the gas report's deployment cost. The same test reported 4,057 gas with linking on and 147,889 with it off. Fixes #17727.

deployCode now charges its caller as a native CREATE or CREATE2 would. It charges the opcode and initcode costs, forwards all but one 64th of the remaining gas to the creation, and settles the result with revm's frame accounting. Isolated gas snapshot sections apply their refund correction at the depth where the caller resumes, and the gas report counts a creation directly under deployCode as a top-level deployment. Explicit vm.deployCode calls are charged too, so existing gas snapshots that use them will increase.

With dynamic test linking, `new` expressions in tests are rewritten to
`vm.deployCode`, which returned all of its gas to the caller. The creation
was left out of test gas, gas snapshots, and the gas report.

Charge the caller as a native CREATE or CREATE2 would, apply isolated
snapshot refund corrections at the caller's depth, and report a creation
under `deployCode` as a top-level deployment in the gas report.

Fixes #17727.
mattsse
mattsse previously approved these changes Oct 22, 2026

@mattsse mattsse left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

lgtm

Enforce the EIP-3860 initcode size limit before charging the synthetic
create, as the CREATE opcode does.

On Amsterdam, charge the EIP-8037 account creation state gas when the
destination is empty, forward the reservoir, and refund the charge when
the create does not deploy. Previously deployCode under-reported a
non-isolated deployment by the creation state gas (407,475 vs 590,422
for native CREATE; now 591,075).

@mablr mablr left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

sgtm

@0xKarl98 0xKarl98 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

lgtm

@0xKarl98
0xKarl98 enabled auto-merge (squash) October 22, 2026 10:28
@0xKarl98
0xKarl98 merged commit fd137b8 into master Oct 22, 2026
23 checks passed
@0xKarl98
0xKarl98 deleted the steven/deploycode-gas-dynamic-linking branch October 22, 2026 10:29
@github-project-automation github-project-automation Bot moved this to Done in Foundry Oct 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

bug(forge test): with dynamic test linking, contracts created with new in tests are left out of test gas and gas snapshots

4 participants