defi-wonderland / smock

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

Get ABI from abstract contract for Fake #56

Closed vmsh0 closed 3 years ago

vmsh0 commented 3 years ago

Is your feature request related to a problem? Please describe. I have an interface. I have to create a mock contract implementing that interface.

Describe the solution you'd like I would like to be able to initialize a Fake using an interface (or in general any abstract contract). E.g.

const myFake = await smock.fake("AnAbstractContract")

Describe alternatives you've considered Manually specifying the ABI in the initialization call.

0xGorilla commented 3 years ago

Hey @vmsh0 !

It actually doesn't work with abstract contracts but for sure you can use the interface or the abi!

Please check out the docs to see how to do it. If you want more detailed example you could check this tests.

If you think the documentation is not clear enough, we would appreciate a PR with your improvements!

Hope that helps

vmsh0 commented 3 years ago

Apologies - I didn't explain myself well enough! :)

I actually have a contract which is an interface, and I'd like to mock that.

I.e.


interface IWhateverInterface
{
  function setSomething(address a, address b) external;
}

Obviously I cannot create a contract factory for this contract. Nor (as far as I can see) can I get an Abi object for it from Ethers and pass it to the Fake constructor. But it would be nonetheless useful to be able to mock an interface without having to creare a mock Solidity implementation - which I think it's the entire point of this plugin.

Am I missing something?

0xGorilla commented 3 years ago

You should be able to use the abi of the interface actually.

Is your interface inside your contracts directory? If it is, hardhat will generate an artifact for it. Look into your artifacts directory for the generated file, it will be something like:

import ICookieArtifact from 'artifacts/contracts/interfaces/ICookie.sol/ICookie.json';

Then you will be able to use the artifact by doing: await smock.fake(ICookieArtifact); or await smock.fake(ICookieArtifact.abi);

vmsh0 commented 3 years ago

Ok, this does work! It's a bit rough on the edges, but it should do fine. Thank you for your help!

0xGorilla commented 3 years ago

Do you have any ideas for improvements? They are more than welcome

vmsh0 commented 2 years ago

The pattern for loading the ABI of concrete contracts is: 1) load the contract with ethers.getContractFactory() 2) pass the result to fake

This abstracts away the details of how the ABI is stored in the filesystem. So it seems natural to me that loading the ABI of an abstract contract should follow at best a similar pattern: 1) load the ABI with some method which takes care of the filesystem representation (can Ethers do that?) 2) pass the result to fake

I'm quite a beginner when it comes to Ethers - I only just got started with it. So I'm not sure whether it has the capability of loading the ABI of an abstract contract. In case it hasn't, I'm not sure whether Smock should implement it by itself.

Although, I would prepend for a "no" - smearing abstractions around different libraries is probably worse than just not having a complete abstraction covering all cases. Ethers should probably do that - what do you think? If you agree, I might just open an issue on their repo referencing this one and see what they think about it.

0xGorilla commented 2 years ago

Actually, when building the V2, we first tried abstracting the abi extraction as you said, but it actually compromised the UX...

The previous solution was to ask users to call ethersInterfaceFromSpec, and then we would simply receive the interface as a ethers.utils.Interface.

I totally agree with you from a smock programmer point of view, the issue is that for every fake you will get 2 lines of code, making the user experience a bit rougher...

Then, maybe a solution is to accept both ways? If you wanna chat about possible improvements/ideas, join our discord server (you can find it on the README). As well, feel free to submit any PRs, we are definitely looking for some help supporting Smock