Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cast): add support for beacon proxies in cast impl #9567

Merged
merged 2 commits into from
Dec 17, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions crates/cast/bin/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -606,7 +606,8 @@ pub enum CastSubcommand {
formula_id: String,
},

/// Fetch the EIP-1967 implementation account
/// Fetch the EIP-1967 implementation for a contract
/// Can read from the implementation slot or the beacon slot.
#[command(visible_alias = "impl")]
Implementation {
/// The block height to query at.
Expand All @@ -615,7 +616,13 @@ pub enum CastSubcommand {
#[arg(long, short = 'B')]
block: Option<BlockId>,

/// The address to get the nonce for.
/// Fetch the implementation from the beacon slot.
///
/// If not specified, the implementation slot is used.
#[arg(long)]
beacon: bool,

/// The address for which the implementation will be fetched.
#[arg(value_parser = NameOrAddress::from_str)]
who: NameOrAddress,

Expand All @@ -632,7 +639,7 @@ pub enum CastSubcommand {
#[arg(long, short = 'B')]
block: Option<BlockId>,

/// The address to get the nonce for.
/// The address from which the admin account will be fetched.
#[arg(value_parser = NameOrAddress::from_str)]
who: NameOrAddress,

Expand Down
4 changes: 2 additions & 2 deletions crates/cast/bin/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -425,11 +425,11 @@ async fn main_args(args: CastArgs) -> Result<()> {
let id = stdin::unwrap_line(id)?;
sh_println!("{}", foundry_common::erc7201(&id))?;
}
CastSubcommand::Implementation { block, who, rpc } => {
CastSubcommand::Implementation { block, beacon, who, rpc } => {
let config = Config::from(&rpc);
let provider = utils::get_provider(&config)?;
let who = who.resolve(&provider).await?;
sh_println!("{}", Cast::new(provider).implementation(who, block).await?)?;
sh_println!("{}", Cast::new(provider).implementation(who, beacon, block).await?)?;
}
CastSubcommand::Admin { block, who, rpc } => {
let config = Config::from(&rpc);
Expand Down
27 changes: 23 additions & 4 deletions crates/cast/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -571,14 +571,33 @@ where
/// ProviderBuilder::<_, _, AnyNetwork>::default().on_builtin("http://localhost:8545").await?;
/// let cast = Cast::new(provider);
/// let addr = Address::from_str("0x7eD52863829AB99354F3a0503A622e82AcD5F7d3")?;
/// let implementation = cast.implementation(addr, None).await?;
/// let implementation = cast.implementation(addr, false, None).await?;
/// println!("{}", implementation);
/// # Ok(())
/// # }
/// ```
pub async fn implementation(&self, who: Address, block: Option<BlockId>) -> Result<String> {
let slot =
B256::from_str("0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc")?;
pub async fn implementation(
&self,
who: Address,
is_beacon: bool,
block: Option<BlockId>,
) -> Result<String> {
let slot = match is_beacon {
true => {
// Use the beacon slot : bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)
B256::from_str(
"0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50",
)?
}
false => {
// Use the implementation slot :
// bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)
B256::from_str(
"0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc",
)?
}
};

let value = self
.provider
.get_storage_at(who, slot.into())
Expand Down
36 changes: 36 additions & 0 deletions crates/cast/tests/cli/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,42 @@ casttest!(rlp, |_prj, cmd| {
"#]]);
});

// test that `cast impl` works correctly for both the implementation slot and the beacon slot
casttest!(impl_slot, |_prj, cmd| {
let eth_rpc_url = next_http_rpc_endpoint();

// Call `cast impl` for the implementation slot (AAVE Proxy)
cmd.args([
"impl",
"0x4965f6FA20fE9728deCf5165016fc338a5a85aBF",
0xvv marked this conversation as resolved.
Show resolved Hide resolved
"--rpc-url",
eth_rpc_url.as_str(),
])
.assert_success()
.stdout_eq(str![[r#"
0xb61306c8eb34a2104d9eb8d84f1bb1001067fa4b

"#]]);
});

casttest!(impl_slot_beacon, |_prj, cmd| {
let eth_rpc_url = next_http_rpc_endpoint();

// Call `cast impl` for the beacon slot
cmd.args([
"impl",
"0xc63d9f0040d35f328274312fc8771a986fc4ba86",
"--beacon",
"--rpc-url",
eth_rpc_url.as_str(),
])
.assert_success()
.stdout_eq(str![[r#"
0xa748ae65ba11606492a9c57effa0d4b7be551ec2

"#]]);
});

// test for cast_rpc without arguments
casttest!(rpc_no_args, |_prj, cmd| {
let eth_rpc_url = next_http_rpc_endpoint();
Expand Down
Loading