Skip to content

Commit

Permalink
feat(cast): support short cut for querying erc20 balance in cast bala…
Browse files Browse the repository at this point in the history
…nce (#6828)
  • Loading branch information
fenghaojiang authored Jan 26, 2024
1 parent c61dc80 commit ee362bd
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 9 deletions.
49 changes: 40 additions & 9 deletions crates/cast/bin/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@
extern crate tracing;

use alloy_primitives::{keccak256, Address, B256};
use cast::{Cast, SimpleCast};
use cast::{Cast, SimpleCast, TxBuilder};
use clap::{CommandFactory, Parser};
use clap_complete::generate;
use ethers_core::types::{BlockId, BlockNumber::Latest};
use ethers_providers::Middleware;
use ethers_core::types::{BlockId, BlockNumber::Latest, NameOrAddress};
use ethers_providers::{Middleware, Provider};
use eyre::Result;
use foundry_cli::{handler, prompt, stdin, utils};
use foundry_common::{
abi::get_event,
fmt::format_tokens,
fs,
runtime_client::RuntimeClient,
selectors::{
decode_calldata, decode_event_topic, decode_function_selector, decode_selectors,
import_selectors, parse_signatures, pretty_calldata, ParsedSignatures, SelectorImportData,
Expand Down Expand Up @@ -201,14 +202,44 @@ async fn main() -> Result<()> {
Cast::new(provider).age(block.unwrap_or(BlockId::Number(Latest))).await?
);
}
Subcommands::Balance { block, who, ether, rpc } => {
Subcommands::Balance { block, who, ether, rpc, erc20 } => {
let config = Config::from(&rpc);
let provider = utils::get_provider(&config)?;
let value = Cast::new(provider).balance(who, block).await?;
if ether {
println!("{}", SimpleCast::from_wei(&value.to_string(), "eth")?);
} else {
println!("{value}");

match erc20 {
Some(token) => {
let chain = utils::get_chain(config.chain, &provider).await?;
let mut builder: TxBuilder<'_, Provider<RuntimeClient>> = TxBuilder::new(
&provider,
NameOrAddress::Address(Address::ZERO.to_ethers()),
Some(NameOrAddress::Address(token.to_ethers())),
chain,
true,
)
.await?;

let account_addr = match who {
NameOrAddress::Name(ens_name) => provider.resolve_name(&ens_name).await?,
NameOrAddress::Address(addr) => addr,
};

builder
.set_args(
"balanceOf(address) returns (uint256)",
vec![format!("{account_addr:#x}")],
)
.await?;
let builder_output = builder.build();
println!("{}", Cast::new(provider).call(builder_output, block).await?);
}
None => {
let value = Cast::new(provider).balance(who, block).await?;
if ether {
println!("{}", SimpleCast::from_wei(&value.to_string(), "eth")?);
} else {
println!("{value}");
}
}
}
}
Subcommands::BaseFee { block, rpc } => {
Expand Down
5 changes: 5 additions & 0 deletions crates/cast/bin/opts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,11 @@ pub enum Subcommands {

#[clap(flatten)]
rpc: RpcOpts,

/// erc20 address to query, with the method `balanceOf(address) return (uint256)`, alias
/// with '--erc721'
#[clap(long, alias = "erc721")]
erc20: Option<Address>,
},

/// Get the basefee of a block.
Expand Down
27 changes: 27 additions & 0 deletions crates/cast/tests/cli/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -556,3 +556,30 @@ casttest!(storage, |_prj, cmd| {
cmd.cast_fuse().args(["storage", usdt, decimals_slot, "--rpc-url", &rpc]);
assert_eq!(cmd.stdout_lossy().trim(), six);
});

casttest!(balance, |_prj, cmd| {
let rpc = next_http_rpc_endpoint();
let usdt = "0xdac17f958d2ee523a2206206994597c13d831ec7";
cmd.cast_fuse().args([
"balance",
"0x0000000000000000000000000000000000000000",
"--erc20",
usdt,
"--rpc-url",
&rpc,
]);
cmd.cast_fuse().args([
"balance",
"0x0000000000000000000000000000000000000000",
"--erc721",
usdt,
"--rpc-url",
&rpc,
]);

let usdt_result = cmd.stdout_lossy();
let alias_result = cmd.stdout_lossy();

assert_ne!(usdt_result, "0x0000000000000000000000000000000000000000000000000000000000000000");
assert_eq!(alias_result, usdt_result);
});

0 comments on commit ee362bd

Please sign in to comment.