Skip to content

Add mockCall and expectCall cheatcodes#403

Merged
gakonst merged 11 commits intofoundry-rs:masterfrom
onbjerg:mock-and-expect-call
Jan 11, 2022
Merged

Add mockCall and expectCall cheatcodes#403
gakonst merged 11 commits intofoundry-rs:masterfrom
onbjerg:mock-and-expect-call

Conversation

@onbjerg
Copy link
Copy Markdown
Member

@onbjerg onbjerg commented Jan 8, 2022

Adds three new cheatcodes: mockCall, expectCall and clearMockedCalls. One is used to return dummy data from either an existing or non-existing contract, and the other is used to assert that a call was made to a specified address with certain calldata.

For both mockCall and expectCall, if the first bytes parameter (which is the expected calldata) is only 4 bytes long then it is treated as a selector.

  • For mockCall this means that any other data in the call is ignored and the result is mocked for an entire function.
  • For expectCall this means that any call to the specified address with the specified selector results in the check passing.

If the calldata is more than 4 bytes long, then the entirety of the calldata is matched for both.

Questions

  • Should we have a cheatcode to clear individual mocks?

Closes https://github.com/gakonst/foundry/issues/382

}

// handle mocked calls
if let Some(ret) = self.state().mocked_calls.get(&(code_address, input.clone())) {
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

this looks pretty expensive, not sure how to get around it thou

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

which part of it you think is expensive? the clone? have you tried without it?

Copy link
Copy Markdown
Member

@gakonst gakonst left a comment

Choose a reason for hiding this comment

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

high level lgtm - curious what @brockelmore thinks

record()
accesses(address)(bytes32[],bytes32[])
expectEmit(bool,bool,bool,bool)
mockCall(address,bytes,bytes)
Copy link
Copy Markdown
Member

@gakonst gakonst Jan 8, 2022

Choose a reason for hiding this comment

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

I was thinking we could also have mockCall(address,bytes) as an override, for checking functions w/o return data in a more user friendly way. Wonder if we could do it such that if the bytes argument is only 8 bytes, that it matches with anything

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

good points. how does abigen work with overrides?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

actually, i'm not sure i understand the first one, can you clarify? i don't see the use case. is it just to avoid a revert?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I was thinking we could also have mockCall(address,bytes) as an override, for checking functions w/o return data in a more user friendly way.

Kinda wish this was this was added. Would be useful for mocking functions that don't have return (external contract calls not in my implementation)

}

// handle mocked calls
if let Some(ret) = self.state().mocked_calls.get(&(code_address, input.clone())) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

which part of it you think is expensive? the clone? have you tried without it?

@onbjerg onbjerg marked this pull request as ready for review January 9, 2022 00:14
Copy link
Copy Markdown
Member

@brockelmore brockelmore left a comment

Choose a reason for hiding this comment

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

lgtm!

@brockelmore
Copy link
Copy Markdown
Member

brockelmore commented Jan 10, 2022

@onbjerg can you add the self.add_debug inside the cheatcode call and the appropriate enum variant in evm-adapters/src/cheatcodes/debugger.rs - then i will merge

@onbjerg
Copy link
Copy Markdown
Member Author

onbjerg commented Jan 11, 2022

Should be good now

@gakonst gakonst merged commit 2bbcf24 into foundry-rs:master Jan 11, 2022
@onbjerg onbjerg deleted the mock-and-expect-call branch January 11, 2022 15:15
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.

feat: expectCall and mockCall

4 participants