foundry-rs / foundry-rs/foundry

feat(forge): Allow marking contracts local in scripts (`vm.markLocal`)

Open
#5,522 0 comments 2 reactions 0 assignees View on GitHub
A-cheatcodes C-forge T-feature
Dominant language
Rust
Stars
10.6k
Forks
2.6k
Avg merge
18h 20m
Merged PRs (30d)
510

Description

### Component

Forge

### Describe the feature you would like

Right now following script would broadcast single call to non-existent contract `CounterDeployer`:
```solidity
pragma solidity ^0.8.13;

import {Script} from "forge-std/Script.sol";
import {Counter} from "src/Counter.sol";

contract CounterDeployer {
function deploy() public returns (address) {
return address(new Counter());
}
}

contract CounterScript is Script {
function run() public {
CounterDeployer deployer = new CounterDeployer();

vm.broadcast(1);
deployer.deploy();
}
}

```

output:
```
Script ran successfully.

## Setting up (1) EVMs.
==========================
Simulated On-chain Traces:

[22380] CounterDeployer::deploy()
└─ ← ()
```

The behavior I propose would allow pattern similar to this:
```solidity
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

import {Script} from "forge-std/Script.sol";
import {Counter} from "src/Counter.sol";

contract CounterDeployer {
function deploy() public returns (address) {
return address(new Counter());
}
}

contract CounterScript is Script {
function run() public {
CounterDeployer deployer = new CounterDeployer();

vm.markLocal(address(deployer)); // Marks deployer contract local (in fact treats it as if it was just part of our test contract)

vm.broadcast(1);
deployer.deploy(); // deploy() call is not broadcasted, but external transactions generated by it are
}
}

```

This would allow cleaner structure of deployment logic, which could be encapsulated in special deployers (I am right now using similar structure, and reuse deployers in tests too). Right now it is possible to get similar behavior using libraries, but they are missing some features contracts have (for example, storage, calls via normal interfaces, inheritance, etc)

I guess this can be implemented via introducing broadcast-specific virtual depth which will not be increased when calls are made to contract marked local

### Additional context

If this is a desired feature, I would be happy to try implement it

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.