pub struct StorageSlotFinder<P, N>where
N: Network,{ /* private fields */ }
Expand description
A utility for finding storage slots in smart contracts, particularly useful for ERC20 tokens.
This struct helps identify which storage slot contains a specific value by:
- Creating an access list to find all storage slots accessed by a function call
- Systematically overriding each slot with an expected value
- Checking if the function returns the expected value to identify the correct slot
§Example
use alloy_contract::StorageSlotFinder;
use alloy_primitives::{address, U256};
use alloy_provider::ProviderBuilder;
let provider = ProviderBuilder::new().connect_anvil();
let token = address!("0x6B175474E89094C44Da98b954EedeAC495271d0F");
let user = address!("0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045");
// Find the storage slot for a user's balance
let finder =
StorageSlotFinder::balance_of(provider, token, user).with_expected_value(U256::from(1000));
if let Some(slot) = finder.find_slot().await? {
println!("Balance stored at slot: {:?}", slot);
}
Implementations§
Source§impl<P, N> StorageSlotFinder<P, N>
impl<P, N> StorageSlotFinder<P, N>
Sourcepub const fn new(
provider: P,
contract: Address,
calldata: Bytes,
expected_value: U256,
) -> Self
pub const fn new( provider: P, contract: Address, calldata: Bytes, expected_value: U256, ) -> Self
Creates a new storage slot finder for a generic function call.
§Arguments
provider
- The provider to use for making callscontract
- The address of the contract to analyzecalldata
- The encoded function call to executeexpected_value
- The value we expect the function to return
For common ERC20 use cases, consider using Self::balance_of
instead.
Sourcepub fn balance_of(provider: P, token_address: Address, user: Address) -> Self
pub fn balance_of(provider: P, token_address: Address, user: Address) -> Self
Convenience constructor for finding the storage slot of an ERC20 balanceOf(address)
mapping.
Uses a default expected value of 1337. Call Self::with_expected_value
to set a different
value.
§Arguments
provider
- The provider to use for making callstoken_address
- The address of the ERC20 token contractuser
- The address of the user whose balance slot we’re finding
Sourcepub const fn with_expected_value(self, value: U256) -> Self
pub const fn with_expected_value(self, value: U256) -> Self
Configures a specific value that should be used in the state override to identify the slot.
Sourcepub async fn find_slot(self) -> Result<Option<B256>, TransportError>
pub async fn find_slot(self) -> Result<Option<B256>, TransportError>
Finds the storage slot containing the expected value.
This method:
- Creates an access list for the function call to identify all storage slots accessed
- Iterates through each accessed slot on the target contract
- Overrides each slot with the expected value using state overrides
- Checks if the function returns the expected value when that slot is overridden
- Returns the first slot that causes the function to return the expected value
§Returns
Ok(Some(slot))
- The storage slot that contains the valueOk(None)
- No storage slot was found containing the valueErr(TransportError)
- An error occurred during RPC calls
§Note
This method assumes that the value is stored directly in a storage slot without any encoding or hashing. For mappings, the actual storage location might be computed using keccak256 hashing.
Trait Implementations§
Source§impl<P: Clone, N> Clone for StorageSlotFinder<P, N>
impl<P: Clone, N> Clone for StorageSlotFinder<P, N>
Source§fn clone(&self) -> StorageSlotFinder<P, N>
fn clone(&self) -> StorageSlotFinder<P, N>
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moreAuto Trait Implementations§
impl<P, N> !Freeze for StorageSlotFinder<P, N>
impl<P, N> RefUnwindSafe for StorageSlotFinder<P, N>where
P: RefUnwindSafe,
N: RefUnwindSafe,
impl<P, N> Send for StorageSlotFinder<P, N>where
P: Send,
impl<P, N> Sync for StorageSlotFinder<P, N>where
P: Sync,
impl<P, N> Unpin for StorageSlotFinder<P, N>
impl<P, N> UnwindSafe for StorageSlotFinder<P, N>where
P: UnwindSafe,
N: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more