defi-wonderland / smock

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

feat: add getVariable function #134

Closed tonykogias closed 2 years ago

tonykogias commented 2 years ago

Description This commit introduces a new function for mock contracts. With getVariable you can view an internal variable's value.

Approach A rough idea of how I approached this problem is: 1) I get an array of slot keys using getVariableStorageSlots that represent the position of the variable's value. 2) I get the values that are stored in those slots using the vmManager.getContractStorage function and providing the contract address and the appropriate slot key. 3) I decoded the values using the decodeVariable function and providing all the values from the above step which results in the variable's value

Metadata

ddnexus commented 2 years ago

This is great and in regular contract deployment it works, however if I try to use it with an OZ UUPS proxy I get:

getVariable is not a function

The contract must be deployed using the upgrades.deployProxy() from the OZ upgrades HH plugin, and I managed to get no complaints from typescript:

const ProxyMock = await smock.mock("MyContract");
const proxyMock = await upgrades.deployProxy(ProxyMock as MockContractFactory<MyContract__factory> & MyContract__factory, [...]) as MyContract & MockContract<MyContract>;

However that does not seem to help. What did I miss?

Is there any possibility to pass a contract instance or a contract factory instead a contractName to smock.moch... Like what we can do with the smock.fake?

Currently I need to use a preprocessor to conditionally add a bunch of accessors to the contract just to handle the private variables for unit testing. The getVariable/setVariable would get rid of all that mess!

Is there any work around I could try?

Thanks