Skip to content

Commit

Permalink
Better error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
naps62 committed Feb 7, 2025
1 parent 4c4f4ce commit c47aa5c
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 21 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ethui-proxy-detect"
version = "0.1.0"
version = "0.2.0"
edition = "2021"
license-file = "./LICENSE"

Expand Down
18 changes: 13 additions & 5 deletions src/comptroller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ use alloy::{
providers::Provider,
};

use crate::{error::DetectProxyResult, utils::u256_to_address, ProxyType};
use crate::{
error::DetectProxyResult,
utils::{bytes_to_b256_fallible, u256_to_address},
ProxyType,
};

const COMPTROLLER_INTERFACE: [B256; 1] = [
// bytes4(keccak256("comptrollerImplementation()")) padded to 32 bytes
Expand All @@ -22,10 +26,14 @@ where
.with_to(address)
.with_input(COMPTROLLER_INTERFACE[0]);

if let Ok(value) = provider.call(&call_0).await {
let b256: B256 = B256::from_slice(&value);
return Ok(Some(ProxyType::Comptroller(u256_to_address(b256.into()))));
let value = match provider.call(&call_0).await {
Ok(value) => value,
Err(e) if e.is_error_resp() => return Ok(None),
Err(e) => return Err(e)?,
};

Ok(None)
match bytes_to_b256_fallible(value) {
None => Ok(None),
Some(b256) => Ok(Some(ProxyType::Comptroller(u256_to_address(b256.into())))),
}
}
19 changes: 14 additions & 5 deletions src/eip897.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ use alloy::{
providers::Provider,
};

use crate::{error::DetectProxyResult, utils::u256_to_address, ProxyType};
use crate::{
error::DetectProxyResult,
utils::{bytes_to_b256_fallible, u256_to_address},
ProxyType,
};

const EIP_897_INTERFACE: [B256; 2] = [
// bytes4(keccak256("implementation()")) padded to 32 bytes
Expand All @@ -24,10 +28,15 @@ where
.with_to(address)
.with_input(EIP_897_INTERFACE[0]);

if let Ok(value) = provider.call(&call_0).await {
let b256: B256 = B256::from_slice(&value);
return Ok(Some(ProxyType::Eip897(u256_to_address(b256.into()))));
let value = match provider.call(&call_0).await {
Ok(value) => value,
Err(e) if e.is_error_resp() => return Ok(None),
Err(e) => return Err(e)?,
};
dbg!(&value);

Ok(None)
match bytes_to_b256_fallible(value) {
None => Ok(None),
Some(b256) => Ok(Some(ProxyType::Eip897(u256_to_address(b256.into())))),
}
}
3 changes: 3 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ use thiserror::Error;
pub enum DetectProxyError {
#[error("RPC error: {0}")]
Provider(#[from] alloy::transports::RpcError<alloy::transports::TransportErrorKind>),

#[error("Invalid length")]
InvalidLength,
}

pub type DetectProxyResult<T> = Result<T, DetectProxyError>;
12 changes: 12 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,16 @@ mod tests {

assert_eq!(result, Some(impl_));
}

#[rstest]
#[case::usdc_impl(address!("0x43506849D7C04F9138D1A2050bbF3A0c054402dd"))]
#[case::dai(address!("0x6B175474E89094C44Da98b954EedeAC495271d0F"))]
#[tokio::test]
async fn not_proxy(#[case] proxy: Address) {
let provider = ProviderBuilder::new().on_http(MAINNET_RPC.clone());

let result = detect_proxy(proxy, &provider).await.unwrap();

assert_eq!(result, None);
}
}
18 changes: 13 additions & 5 deletions src/safe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ use alloy::{
providers::Provider,
};

use crate::{error::DetectProxyResult, utils::u256_to_address, ProxyType};
use crate::{
error::DetectProxyResult,
utils::{bytes_to_b256_fallible, u256_to_address},
ProxyType,
};

const SAFE_INTERFACE: [B256; 1] = [
// bytes4(keccak256("masterCopy()")) padded to 32 bytes
Expand All @@ -22,10 +26,14 @@ where
.with_to(address)
.with_input(SAFE_INTERFACE[0]);

if let Ok(value) = provider.call(&call_0).await {
let b256: B256 = B256::from_slice(&value);
return Ok(Some(ProxyType::Safe(u256_to_address(b256.into()))));
let value = match provider.call(&call_0).await {
Ok(value) => value,
Err(e) if e.is_error_resp() => return Ok(None),
Err(e) => return Err(e)?,
};

Ok(None)
match bytes_to_b256_fallible(value) {
None => Ok(None),
Some(b256) => Ok(Some(ProxyType::Safe(u256_to_address(b256.into())))),
}
}
16 changes: 12 additions & 4 deletions src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ pub(crate) async fn storage_slot_as_address<N, P: Provider<N>>(
where
N: Network,
{
let slot = provider
.get_storage_at(address, slot.into())
.latest()
.await?;
let slot = match provider.get_storage_at(address, slot.into()).latest().await {
Ok(value) => value,
Err(e) if e.is_error_resp() => return Ok(None),
Err(e) => return Err(e)?,
};

if !slot.is_zero() {
return Ok(Some(u256_to_address(slot)));
Expand All @@ -30,3 +31,10 @@ pub(crate) fn u256_to_address(u256: U256) -> Address {
let bytes: Bytes = u256.to_be_bytes::<32>().into();
Address::from_slice(&bytes[12..])
}

pub(crate) fn bytes_to_b256_fallible(bytes: Bytes) -> Option<B256> {
if bytes.len() != B256::ZERO.len() {
return None;
}
Some(B256::from_slice(&bytes))
}

0 comments on commit c47aa5c

Please sign in to comment.