defi-wonderland / smock

The Solidity mocking library
MIT License
321 stars 40 forks source link

Setting a FakeContract return value as a struct "Error: call revert exception" #94

Closed richard-massless closed 2 years ago

richard-massless commented 3 years ago

Describe the bug When setting the return value of the function on a FakeContract the call is reverted.

Reproduction steps

    mapping(uint256 => SomeType) public typeMap

    struct SomeType {
        uint256 id;
        string name;
    }
  fakeContract.getType.returns({
    id: BigNumber.from(1),
    name: "Type1",
  });

Returns Error: call revert exception

Expected behavior Setting the return value of fakeContract.getType to mirror the solidity struct will should be able to be set without causing a revert.

Workaround Setting the returns value of fakeContract.typeMap as an array will not cause the Error: call revert exception

  fakeContract.typeMap.returns([
   BigNumber.from(1),
    "Type1",
  ]);

Workaround issue Let me know if this should be a new ticket but it appears heavily related: When testing a function on the real contract, which in turn calls fakeContract.typeMap() the response is: Error: Transaction reverted: function returned an unexpected amount of data

0xGorilla commented 3 years ago

Yep, actually Smock is failing to encode the return value of public mappings that have an Struct as value.

In order to fix this we will need to convert the given object to an array, and the order of the keys should be given by the contract ABI.

It's not that simple to fix, but it is completely doable, I will try to do it as soon as possible, but it will take me some days since I am really busy lately

0xGorilla commented 2 years ago

This is finally fixed! 🥳 It should work even with nested structs inside mappings.

If you would like to try it out right now you could install the canary version: 0.0.0-294819d5, if not, it will be released soon.