foundry icon indicating copy to clipboard operation
foundry copied to clipboard

feat(forge): inspect storage slot value

Open b1u3h4t opened this issue 2 years ago • 5 comments

Motivation

After deploying the contract, it is often necessary to check whether the parameters are set successfully, so here is a simple method to query the value of the slot corresponding to the contract variable.

Solution

Obtain the value of the specified slot in the contract through getStorageAt, and then print it in a developer-friendly way to facilitate the review of related variables.

TODO

  • [ ] fetch etherscan source and compile
  • [ ] check upgradeable contract and implementation contract bytecode
  • [ ] storage value for mapping, array and so on
  • [ ] more tests

b1u3h4t avatar Jul 27 '22 15:07 b1u3h4t

Imo this should be in Cast where we also already have cast storage - could just add a flag or something to it to get this functionality

onbjerg avatar Jul 28 '22 15:07 onbjerg

Imo this should be in Cast where we also already have cast storage - could just add a flag or something to it to get this functionality

It makes sense, maybe we need to expose more forge-related contract interfaces to cast, so that cast can expand more transaction-related details from a contract perspective.

b1u3h4t avatar Jul 28 '22 16:07 b1u3h4t

I agree this is useful, but big +1 that this should not be part of forge. forge inspect's purpose is to simply make solc output such as storage layout more accessible and readable.

Right now cast storage <address> <slot> prints the the specified slot. Expanding on @onbjerg's suggestion, I'd propose cast storage <address> (i.e. when no slot is specified) to behave as follows:

  1. Fetch the bytecode of the provided address.
  2. If we're in a foundry project, check artifacts for matching bytecode + recompile if needed to get storage layout.
  3. Otherwise, fetch source from etherscan and compile it with the specified settings to get storage layout (this is also useful for debugging txs against a live network where we'd recompile to get source maps).
  4. Print variable names, slots, sizes, offsets, and decoded values in a table similar to the existing one that you get with forge inspect MyContract storage-layout --pretty.

Note this PR does not properly handle dynamic types. It will print the length of an array for array types, and zero for mappings because it doesn't know the keys. I think that's ok for the first version, but I'd love for the next iteration to figure out array lengths and all mapping keys to print the all storage. @banteg has a POC for doing this here: https://github.com/banteg/storage-layout

mds1 avatar Jul 29 '22 00:07 mds1

Definitely +1 for @mds1 cast storage <address> proposal, I think it would also be cool to have a --blocknumber param that lets you do historical queries so that you can write a script that can see how state changes in a contract over a range of blocks

tynes avatar Aug 02 '22 16:08 tynes

Agreed, --block <blockNumber/earliest/latest/pending> is the syntax used elsewhere in cast which we should support here too

mds1 avatar Aug 03 '22 04:08 mds1

hey @b1u3h4t what are the best next steps here?

(we at a minimum want a unit test here)

gakonst avatar Aug 15 '22 18:08 gakonst

Ping @b1u3h4t

onbjerg avatar Aug 23 '22 16:08 onbjerg

On further thought I think we should go wiht @mds1 suggestion. Closing given stale, and we can revisit! Thanks!

gakonst avatar Sep 19 '22 21:09 gakonst