foundry
foundry copied to clipboard
Feat: `mockCall` with actions
Component
Forge
Describe the feature you would like
Currently, the mockCall()
method can only return values. It would be useful to have a similar method called mockCallWithAction()
, which takes in encoded calldata and address as additional parameter. For example, in ERC4626 vault's withdraw()
method returns the asset amount as well as performs a transfer call which sends funds to the caller/recipient.
So, instead of just doing:
vm.mockCall(
address(vault),
abi.encodeWithSelector(IERC4626.withdraw.selector),
true
);
We can do something like this:
struct Action {
address target,
bytes data
}
bytes memory transferCalldata = abi.encodeWithSelector(IERC20.transfer.selector, receiver, 10e18);
Actions[] memory actions = new Action()[1];
actions.push({target: tokenAddress, data: transferCalldata});
vm.mockCallWithActions(
address(vault),
abi.encodeWithSelector(IERC4626.withdraw.selector),
true,
actions
);
It would also be nice to include actions the ability to trigger specific cheatcodes like deal()
, etc.,
This would be super useful during integration testing. Happy to take this on. Let me know wdyt.
Additional context
No response
bumping this. cc: @mds1 @mattsse
For something like this I think you are better off writing a custom mock solidity contract and etching it at the target address. I would be hesitant to implement this feature because it seems there are a wide range of potential side effects and edge cases, and it's not intuitive how everything should behave or work. Some examples:
- Call parameters: What if I want to send value, or do a delegatecall instead of a call, or specify a gas limit? What if one action reverts? You quickly need to expand that
Action
struct, and provide lots of overloads if you want good UX - What if the mocked call is the same as the action? Revert, or do two separate things on each invocation?
- If the action calls back into the mocked call, do we still want the mocked value returned? "Yes" isn't representative if the action should have impacted the returned value of the mock, and I'd need to clear mocked calls in between
There are arguments in favor for any answer, but none of them are clearly correct for a vast majority of use cases, meaning the cheatcode behavior will be ambiguous and nonintuitive. Whereas with a custom mock contract you can get the precise behavior you want with no ambiguity :)
Thanks @PraneshASP for the suggestion
Marking as not planned
per the comment above
Agreed that a custom mock contract is better alternative, thanks for the suggestion @mds1!