Open ashhanai opened 3 years ago
Hey @ashhanai , it's great to see that people are actually using Smock v2!
Your proposal sounds super interesting, could you please provide a test that would illustrate better the use case?
Hi @0xGorilla, sure.
Create a token abstraction and pack ERC20, ERC721 & ERC1155 into one struct Token. Implement library, that uses Token struct and defines functions for transfer and approve transfers of underlying ERC20 / 721 / 1155 tokens. Use this token to eliminate unnecessary type check every time transfer / approval should occur.
My contract is transferring tokens via this abstraction and I want to test, that it calls the right function of the library (library is tester separately, so just the call check is enough).
The issue here is that my contract is linking the library and using it like this: using TokenAbstract for Token;
so even though the function is defined like this function transfer(Token memory _token, address _receiver, uint256 _amount)
the transfer call is made e.g. like this token.transfer(receiver, 10)
.
I hope I made the use case more understandable.
I meant forking this repo and creating a real test (that would fail), from there I will grab the test and try to make it pass.
Is that possible? From there it will be easier to develop a solution
@0xGorilla this is related to our plan to add mocking for libraries in general, which requires that deeper rewrite we discussed. It's definitely a huge value add but will take some effort.
This is still not solved, but at least right now you can deploy a mock that uses a library, check out the tests of https://github.com/defi-wonderland/smock/pull/68
I've been using smock a whole lot lately and have been also working with the Ethereum Diamonds (https://eips.ethereum.org/EIPS/eip-2535). Diamonds use a lot of libraries and being able to mock a library would make unit testing Diamond Facet's 1000x easier.
First of all, I'm completely mind blown by what smock
does. Being in the Solidity ecosystem since it started, and for having had to test stuff manually with solidity mocks keeping tracks of args, smock
absolutely rocks.
Now - mocking libraries - this is a really tricky topic. Solidity libraries are weird beasts...
I'd like to give a bit of feedback here, from my experience with smock
just now.
smock.fake
a library. Things just crash.smock.mock
a library factory. Things got better.getCall(0)
is just undefined
).Now regarding 2 - during this step, I discovered a few things: You might think that you're using a library while you're in fact not. Basically, if your library has either one of:
internal
or a private
in the library? Then this function will get inlined by the compiler, and put directly in the caller. Therefore - mocking cannot work. This can be particularly misleading - and I know lots of people discover this at their own expense, when they "think" their logic is deployed neat and tidy separately, and in the end discover that just a few functions are actually deployed in their library and all others are inlined, bloating their contracts.public
, there's a huge caveat here. If your public
or even external
library function uses an argument passed as storage
and / or of type struct
, then you'll also get that inlined.To finish - I might have forgotten a few things here - I would really like that smock
adds support for libraries.
Came across this issue today, it'd be great to have support for this! We have the exact same use case as @ashhanai
Make it possible to mock libraries in contracts.
Example: I am using my own library Lib with struct Lib.Str in my contract Con.
using Lib for Lib.Str;
My Lib has few methods which works with Lib.Str:
function foo(Lib.Str memory _str, uint256 _amount) external
I am calling this functions in my contract like this:
str.foo(10);
I would really use mocking this library and be able to see, if my contract (which is using this library) called function
foo
, how many times and so on.