Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix single broadcast/prank nonce setting #5727

Merged
merged 4 commits into from
Aug 29, 2023

Conversation

klkvr
Copy link
Member

@klkvr klkvr commented Aug 25, 2023

Motivation

Closes #5635

Solution

Remove single call broadcast/prank from cheatcodes inspector only when we have came back to the broadcast/prank initialization depth

I think this should get a careful review from someone with deep knowledge of evm crate architecture

@klkvr klkvr changed the title Fix single broadcast/prank Fix single broadcast/prank nonce setting Aug 25, 2023
@nhtyy
Copy link
Contributor

nhtyy commented Aug 25, 2023

Nice! This makes sense to me wrt the delegatecall issue.

but i don't think this will fix the issue of the broadcast field on the cheatcode inspector being set to None if there is two broadcast calls in the same script

maybe @Evalir can clear up semantics here

@klkvr
Copy link
Member Author

klkvr commented Aug 25, 2023

The issue actualy happens not only with delegatecalls, but with any broadcasted calls which result in subsequent calls/delegatecalls to other contracts because we are dropping broadcast field at the end of the first such call

For me it solved the issue with two broadcasts in the same script which I explained in the issue

@nhtyy
Copy link
Contributor

nhtyy commented Aug 25, 2023

oh yeah @klkvr just tested and you're totally right my bad

while it is true that broadcast is set to None, on the next vm.broadcast, which is a call to the HEVM address, theres a call to cheatcodes::env::apply in the cheatcode inspector call that leads to this function being executed which resets the broadcast field!

fn broadcast(
state: &mut Cheatcodes,
new_origin: Address,
original_caller: Address,
original_origin: Address,
depth: u64,
single_call: bool,
) -> Result {
ensure!(
state.prank.is_none(),
"You have an active prank. Broadcasting and pranks are not compatible. \
Disable one or the other"
);
ensure!(state.broadcast.is_none(), "You have an active broadcast already.");
let broadcast = Broadcast { new_origin, original_origin, original_caller, depth, single_call };
state.broadcast = Some(broadcast);
Ok(Bytes::new())
}

So ya great find and great fix!

@Evalir Evalir requested review from mattsse and Evalir August 25, 2023 15:08
Copy link
Member

@Evalir Evalir left a comment

Choose a reason for hiding this comment

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

lgtm! just gonna be really careful with this and test

Comment on lines 761 to 764

if prank.single_call {
std::mem::take(&mut self.prank);
}
Copy link
Member

Choose a reason for hiding this comment

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

Let's add docs on the rationale as to why this is applied iff the outer if runs—it's a change on the previous behavior and I'm a bit apprehensive it might "fix" (or break) behavior that has come to be expected. Will test this locally


if broadcast.single_call {
std::mem::take(&mut self.broadcast);
if broadcast.single_call {
Copy link
Member

Choose a reason for hiding this comment

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

ditto here and the others

@klkvr
Copy link
Member Author

klkvr commented Aug 25, 2023

Hey @Evalir, I have added some comments. However, IMO, the previous behavior was slightly less intuitive. I'm not entirely sure if we actually need an explanation here. The broadcast cleaning outside of the if data.journaled_state.depth() == broadcast.depth condition resulted in the logic inside that if statement not being executed in certain cases, which seems to be unexpected. So, the current implementation looks more suspicious to me. But yes, it really needs review and should be documented even if we decide to keep the current behavior

@Evalir Evalir merged commit 6c4c68a into foundry-rs:master Aug 29, 2023
15 checks passed
mikelodder7 pushed a commit to LIT-Protocol/foundry that referenced this pull request Sep 12, 2023
* Fix single broadcast

* Add comments

* rustfmt

---------

Co-authored-by: Enrique Ortiz <hi@enriqueortiz.dev>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

vm.broadcast() sets incorrect nonce for txs
3 participants