foundry-rs / foundry-rs/foundry

feat(`cheatcode`): add `vm.waitForTransaction` for getting tx and receipt info in scripts

Open
#3,589 4 comments 6 reactions 0 assignees View on GitHub
A-cheatcodes C-forge T-feature
Dominant language
Rust
Stars
10.6k
Forks
2.6k
Avg merge
16h 38m
Merged PRs (30d)
511

Description

### Component

Forge

### Describe the feature you would like

### Problems

First problem: In scripts, there's a frontrunning footgun you have to be careful of. Here's an example with pseudocode:
- Transaction 1: Call `gnosisSafeFactory.createSafe()` to deploy a safe with CREATE (so contract nonce matters)
- Transaction 2: Transfer 10 DAI to the safe

Forge will simulate tx1, get the address of the safe, and send tokens to that in tx2. But if someone else deploys a gnosis safe in between, the address of your safe changes and you send tokens to the wrong address. I've encountered this on mainnet, so it's not just theoretical 🙂

(Note that an alternative solution to the first problem is to have `--slow` wait for the tx to be mined, then requery for all data before the next transaction)

Second problem: The default broadcast artifacts are not ideal for everyone. For example, if you have upgradeable contracts, you may want `.json` for all your contract deploys, instead of one JSON file for each script execution. This is doable by using the file writing cheats within a script, but currently you can't access tx and receipt info so you have more limited logging capabilities than forge itself.

### Solution

```solidity
function waitForTransaction() external returns (Tx memory tx, Receipt memory receipt);
```

(or if ethers-rs has a function of the same purpose with a different name, the cheatcode can match that name)

This cheatcode can be called after each broadcasted transaction. It will wait for the transaction to be mined, return the tx and receipt data, then continue.

One issue here is the returned structs will differ depending on if the tx is type 0, 1, or 2. As a result we probably need to just return `bytes memory` for both `tx` and `receipt`, and use the existing JSON [helper structs](https://github.com/foundry-rs/forge-std/blob/2a2ce3692b8c1523b29de3ec9d961ee9fbbc43a6/src/Test.sol#L469) with forge-std methods to help decode the transactions, which is ok.

One other issue is that this is the first cheatcode that would be "script only", i.e. this wouldn't make much sense in tests, though I guess it could work there too but for all transactions?

### Additional context

_No response_

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.