Skip to content

mockCall's calldata partial matching behaviour doesn't work as expected #1604

@AdithyaNarayan

Description

@AdithyaNarayan

Component

Forge

Have you ensured that all of these are up to date?

  • Foundry
  • Foundryup

What version of Foundry are you on?

forge 0.2.0 (4604a42 2022-05-12T00:04:28.117376+00:00)

What command(s) is the bug in?

forge test

Operating System

macOS (Apple Silicon)

Describe the bug

The mockCall's partial calldata matching is not working as expected.

import "forge-std/Test.sol";

contract Contract {
    function f(uint256 a, uint256 b) public pure returns(uint256) {
      return a + b; 
    }
}

contract ContractTest is Test {
    function setUp() public {}

    function testExample() public {
        Contract target = new Contract();

        vm.mockCall(address(target), abi.encodeWithSelector(target.f.selector), abi.encode(10)); 
        vm.mockCall(address(target), abi.encodeWithSelector(target.f.selector, 2), abi.encode(20)); 
        vm.mockCall(address(target), abi.encodeWithSelector(target.f.selector, 2, 3), abi.encode(30)); 

        assertEq(target.f(1, 2), 10);
        assertEq(target.f(2, 2), 20); // Expected: 20, Actual: 10
        assertEq(target.f(2, 3), 30);
    }
}

This is probably because of the way the partial matching works, since it check for a match, and if not found, iterates and returns the first match. In this case, it looks like the iteration is happening from least specific to most specific when it should be the other way around

Metadata

Metadata

Labels

Type

No type

Projects

Status

Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions