-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Description
Component
Forge
Describe the feature you would like
Currently, the vm.deployCode
cheatcode works perfectly for deploying standard Vyper contracts. However, it reverts when attempting to deploy a Vyper contract that is meant to be a blueprint (one that would be deployed using create_from_blueprint
).
The ideal solution would be a native, straightforward cheatcode to deploy Vyper blueprint contracts. This could be implemented in one of two ways:
- Extend
deployCode
: Enhance the existingdeployCode
(anddeployCodeTo
) cheatcode to accept additional args and correctly handle Vyper blueprint source files. - Add a new cheatcode: Introduce a dedicated cheatcode, such as
deployBlueprint(string memory path)
ordeployBlueprintCode(string memory code)
, specifically for this purpose.
Either approach would be a significant improvement over the current state.
I have a working solution that uses vm.ffi
to call the vyper
compiler with the correct flags and then deploys the resulting bytecode using inline assembly.
While this workaround is functional, it's not ideal because it requires the --ffi
flag and involves manual, low-level assembly, which is less accessible and more error-prone than a dedicated cheatcode.
/// @notice Deploys a Vyper blueprint contract using ffi to compile and assembly to create.
/// @param path The path to the Vyper source file.
/// @param label A label for the deployed blueprint address in traces.
/// @return blueprint The address of the deployed blueprint contract.
function deployBlueprint(
string memory path,
string memory label
) internal returns (address blueprint) {
// Prepare the command to compile the contract to blueprint bytecode
string[] memory inputs = new string[](4);
inputs[0] = "vyper";
inputs[1] = "-f";
inputs[2] = "blueprint_bytecode";
inputs[3] = path;
// Execute the command via FFI to get the deployment code
bytes memory bytecode = vm.ffi(inputs);
// Deploy the bytecode using the CREATE opcode
assembly {
// create(value, offset, length)
blueprint := create(0, add(bytecode, 0x20), mload(bytecode))
}
require(blueprint != address(0), "deployBlueprint: Deployment failed");
vm.label(blueprint, string.concat(label, " Blueprint"));
}
Example usage:
// Deploy the Twocrypto.vy contract as a blueprint
address twocryptoBlueprint = deployBlueprint(
"contracts/testing/twocrypto/Twocrypto.vy",
"Twocrypto"
);
Additional context
No response
Metadata
Metadata
Assignees
Labels
Type
Projects
Status