Skip to content

Instantly share code, notes, and snippets.

@mds1
Created September 8, 2021 12:36
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mds1/5b06a440f4319dbad0c2d7c15cc2c1e5 to your computer and use it in GitHub Desktop.
Save mds1/5b06a440f4319dbad0c2d7c15cc2c1e5 to your computer and use it in GitHub Desktop.
Solidity and Vyper storage slot calcuations
import { defaultAbiCoder } from '@ethersproject/abi';
import { hexZeroPad, hexStripZeros } from '@ethersproject/bytes';
import { keccak256 } from '@ethersproject/keccak256';
// `defaultAbiCoder.encode` is equivalent to Solidity's `abi.encode()`, and we strip leading zeros from the hashed
// value to conform to the JSON-RPC spec: https://ethereum.org/en/developers/docs/apis/json-rpc/#hex-value-encoding
// Returns the storage slot for a Solidity mapping from an `address` to a value, given the slot of the mapping itself,
// `mappingSlot`. Read more at https://docs.soliditylang.org/en/latest/internals/layout_in_storage.html#mappings-and-dynamic-arrays
const getSolidityStorageSlot = (mappingSlot: string, address: string) => {
return hexStripZeros(keccak256(defaultAbiCoder.encode(['address', 'uint256'], [address, mappingSlot])));
};
// Returns the storage slot for a Vyper mapping from an `address` to a value, given the slot of the mapping itself,
// `mappingSlot`. Not guaranteed to work for all Vyper versions since storage layout is not yet stable. More info: https://twitter.com/big_tech_sux/status/1420159854170152963
const getVyperStorageSlot = (mappingSlot: string, address: string) => {
return hexStripZeros(keccak256(defaultAbiCoder.encode(['uint256', 'address'], [mappingSlot, address])));
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment