foundry: bug: `mockCall` not working as expected

The tests in CheatCodes.sol passed, however the test below fails. Tagging @onbjerg here since you implemented this feature originally in #403

pragma solidity 0.8.10;

import "ds-test/test.sol";

interface Vm {
  function mockCall(address,bytes calldata,bytes calldata) external;
}

contract MyContract {
  function outer() public returns (uint256) {
    return inner();
  }

  function inner() public returns (uint256) {
    return 5;
  }
}

contract MyContractTest is DSTest {
  MyContract c;
  Vm vm = Vm(address(bytes20(uint160(uint256(keccak256('hevm cheat code'))))));

  function testMock() public {
    c = new MyContract();
    assertEq(c.inner(), 5);
    assertEq(c.outer(), 5);

    uint256 _newVal = 10;
    vm.mockCall(address(c), abi.encodeWithSelector(c.inner.selector), abi.encode(_newVal));

    assertEq(c.inner(), _newVal); // passes
    assertEq(c.outer(), _newVal); // fails
  }
}

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 15 (5 by maintainers)

Most upvoted comments

Yeah, it’s pretty much impossible for us (as far as I can tell) to hook into the actual stepping of the EVM itself with Sputnik, but revm inspectors solve this by giving us full control

Maybe the documentation was a bit confusing - outer is not making a call in the EVM sense of the word, it is just jumping to a new location in the code of the contract. mockCall only works for calls between accounts. I think my usage of the word “internal call” (by which I mean a contract calling another contract) might have lead to that confusion?