-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Description
Component
Forge
Proposal
Add cheatcode that lets you hook into Solidity's built-in new <ContractName>(...constructorArgs) syntax to retrieve the initcode. This will ensure that it's easy and type-safe for developers to construct and access the initcode payload. This can be achieved via the addition of a single new cheatcode: vm.interceptInitcode().
Upon invocation this cheatcode would cause the very next create/create2 to fail setting the returndata buffer (error data) to the initcode. Interacting with this opcode to get the initcode would then look like this:
vm.interceptInitcode();
bytes memory initcode;
try new MyContract(param1, param2) { assert(false); /* optional: Makes use of cheatcode more explicit */ }
catch (bytes memory interceptedInitcode) { initcode = interceptedInitcode; }Motivation
In foundry scripts the primary action is deploying contracts. In many contexts this is done via create factories like the well-known CREATE2 factory, @pcaversaccio CreateX or my own Create3 based deploy factory "SubZero". In all these cases developers need access to their contract's initcode inside their script and sometimes tests.
Foundry & Solidity already give you several ways of accessing creationCode via either vm.getCode(<artifactName>) or Solidity's type(ContractName).creationCode the issue arrises when wanting to access the initcode payload which is the creationCode together with the correctly encoded constructor arguments.
The only way to achieve this currently is to manually encode and concatenate the creation code and the constructor arguments. This is sub-optimal as it is not type-safe and can lead to errors/bugs if the script and contract ever get out-of-sync:
bytes memory initcode = abi.encodePacked(type(VanityMarket).creationCode, abi.encode(MARKET_OWNER));This is error prone, leading to errors/corrupted initcode data when the contract implementation and script diverge.
Spec
- Add
interceptingNext: boolflag to cheatcodes - Add
vm.interceptInitcodecheatcode, setsinterceptNexttotrueiffalse, gives an error otherwise - Add
create/create2inspector. Upon a create invocation, ifinterceptNext = true, set tofalseand cause an immediate revert returning thecreateinitcode as error data in the returndata buffer. Otherwise ifinterceptNext = falseproceed with normal EVMcreate/create2semantics
Rationale
Shouldn't this be a Solidity Feature?
Yes, but considering how fast Solidity moves and that this doesn't seem like a huge change in foundry, only adding a single cheatcode, I think it's a worthwhile extension.
Why so verbose, why not 1 cheatcode for activating the intercept and another for retrieving the intercept?
The proposed design ensures minimal additions in terms of opcodes and also makes it explicit when you're actually deploying a contract vs. retrieving the initcode. This minimizes the potential footgun of accidentally deploying an additional/unwanted contract in your scripts/test when you refactor code.
Additional context
No response
Metadata
Metadata
Assignees
Labels
Type
Projects
Status