Skip to content

Commit f61c113

Browse files
authored
feat(cast): more erc20 methods (#12381)
* feat(cast): more erc20 methods * chore: use helper fn * fix: drop `transferFrom`
1 parent be810cb commit f61c113

File tree

4 files changed

+456
-130
lines changed

4 files changed

+456
-130
lines changed

crates/cast/src/cmd/erc20.rs

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,16 @@ sol! {
1919
#[sol(rpc)]
2020
interface IERC20 {
2121
#[derive(Debug)]
22+
function name() external view returns (string);
23+
function symbol() external view returns (string);
24+
function decimals() external view returns (uint8);
25+
function totalSupply() external view returns (uint256);
2226
function balanceOf(address owner) external view returns (uint256);
2327
function transfer(address to, uint256 amount) external returns (bool);
2428
function approve(address spender, uint256 amount) external returns (bool);
2529
function allowance(address owner, address spender) external view returns (uint256);
30+
function mint(address to, uint256 amount) external;
31+
function burn(uint256 amount) external;
2632
}
2733
}
2834

@@ -112,6 +118,104 @@ pub enum Erc20Subcommand {
112118
#[command(flatten)]
113119
rpc: RpcOpts,
114120
},
121+
122+
/// Query ERC20 token name.
123+
#[command(visible_alias = "n")]
124+
Name {
125+
/// The ERC20 token contract address.
126+
#[arg(value_parser = NameOrAddress::from_str)]
127+
token: NameOrAddress,
128+
129+
/// The block height to query at.
130+
#[arg(long, short = 'B')]
131+
block: Option<BlockId>,
132+
133+
#[command(flatten)]
134+
rpc: RpcOpts,
135+
},
136+
137+
/// Query ERC20 token symbol.
138+
#[command(visible_alias = "s")]
139+
Symbol {
140+
/// The ERC20 token contract address.
141+
#[arg(value_parser = NameOrAddress::from_str)]
142+
token: NameOrAddress,
143+
144+
/// The block height to query at.
145+
#[arg(long, short = 'B')]
146+
block: Option<BlockId>,
147+
148+
#[command(flatten)]
149+
rpc: RpcOpts,
150+
},
151+
152+
/// Query ERC20 token decimals.
153+
#[command(visible_alias = "d")]
154+
Decimals {
155+
/// The ERC20 token contract address.
156+
#[arg(value_parser = NameOrAddress::from_str)]
157+
token: NameOrAddress,
158+
159+
/// The block height to query at.
160+
#[arg(long, short = 'B')]
161+
block: Option<BlockId>,
162+
163+
#[command(flatten)]
164+
rpc: RpcOpts,
165+
},
166+
167+
/// Query ERC20 token total supply.
168+
#[command(visible_alias = "ts")]
169+
TotalSupply {
170+
/// The ERC20 token contract address.
171+
#[arg(value_parser = NameOrAddress::from_str)]
172+
token: NameOrAddress,
173+
174+
/// The block height to query at.
175+
#[arg(long, short = 'B')]
176+
block: Option<BlockId>,
177+
178+
#[command(flatten)]
179+
rpc: RpcOpts,
180+
},
181+
182+
/// Mint ERC20 tokens (if the token supports minting).
183+
#[command(visible_alias = "m")]
184+
Mint {
185+
/// The ERC20 token contract address.
186+
#[arg(value_parser = NameOrAddress::from_str)]
187+
token: NameOrAddress,
188+
189+
/// The recipient address.
190+
#[arg(value_parser = NameOrAddress::from_str)]
191+
to: NameOrAddress,
192+
193+
/// The amount to mint.
194+
amount: String,
195+
196+
#[command(flatten)]
197+
rpc: RpcOpts,
198+
199+
#[command(flatten)]
200+
wallet: WalletOpts,
201+
},
202+
203+
/// Burn ERC20 tokens.
204+
#[command(visible_alias = "bu")]
205+
Burn {
206+
/// The ERC20 token contract address.
207+
#[arg(value_parser = NameOrAddress::from_str)]
208+
token: NameOrAddress,
209+
210+
/// The amount to burn.
211+
amount: String,
212+
213+
#[command(flatten)]
214+
rpc: RpcOpts,
215+
216+
#[command(flatten)]
217+
wallet: WalletOpts,
218+
},
115219
}
116220

117221
impl Erc20Subcommand {
@@ -121,6 +225,12 @@ impl Erc20Subcommand {
121225
Self::Approve { rpc, .. } => rpc,
122226
Self::Balance { rpc, .. } => rpc,
123227
Self::Transfer { rpc, .. } => rpc,
228+
Self::Name { rpc, .. } => rpc,
229+
Self::Symbol { rpc, .. } => rpc,
230+
Self::Decimals { rpc, .. } => rpc,
231+
Self::TotalSupply { rpc, .. } => rpc,
232+
Self::Mint { rpc, .. } => rpc,
233+
Self::Burn { rpc, .. } => rpc,
124234
}
125235
}
126236

@@ -154,6 +264,46 @@ impl Erc20Subcommand {
154264
.await?;
155265
sh_println!("{}", format_uint_exp(balance))?
156266
}
267+
Self::Name { token, block, .. } => {
268+
let token = token.resolve(&provider).await?;
269+
270+
let name = IERC20::new(token, &provider)
271+
.name()
272+
.block(block.unwrap_or_default())
273+
.call()
274+
.await?;
275+
sh_println!("{}", name)?
276+
}
277+
Self::Symbol { token, block, .. } => {
278+
let token = token.resolve(&provider).await?;
279+
280+
let symbol = IERC20::new(token, &provider)
281+
.symbol()
282+
.block(block.unwrap_or_default())
283+
.call()
284+
.await?;
285+
sh_println!("{}", symbol)?
286+
}
287+
Self::Decimals { token, block, .. } => {
288+
let token = token.resolve(&provider).await?;
289+
290+
let decimals = IERC20::new(token, &provider)
291+
.decimals()
292+
.block(block.unwrap_or_default())
293+
.call()
294+
.await?;
295+
sh_println!("{}", decimals)?
296+
}
297+
Self::TotalSupply { token, block, .. } => {
298+
let token = token.resolve(&provider).await?;
299+
300+
let total_supply = IERC20::new(token, &provider)
301+
.totalSupply()
302+
.block(block.unwrap_or_default())
303+
.call()
304+
.await?;
305+
sh_println!("{}", format_uint_exp(total_supply))?
306+
}
157307
// State-changing
158308
Self::Transfer { token, to, amount, wallet, .. } => {
159309
let token = token.resolve(&provider).await?;
@@ -173,6 +323,23 @@ impl Erc20Subcommand {
173323
let tx = IERC20::new(token, &provider).approve(spender, amount).send().await?;
174324
sh_println!("{}", tx.tx_hash())?
175325
}
326+
Self::Mint { token, to, amount, wallet, .. } => {
327+
let token = token.resolve(&provider).await?;
328+
let to = to.resolve(&provider).await?;
329+
let amount = U256::from_str(&amount)?;
330+
331+
let provider = signing_provider(wallet, &provider).await?;
332+
let tx = IERC20::new(token, &provider).mint(to, amount).send().await?;
333+
sh_println!("{}", tx.tx_hash())?
334+
}
335+
Self::Burn { token, amount, wallet, .. } => {
336+
let token = token.resolve(&provider).await?;
337+
let amount = U256::from_str(&amount)?;
338+
339+
let provider = signing_provider(wallet, &provider).await?;
340+
let tx = IERC20::new(token, &provider).burn(amount).send().await?;
341+
sh_println!("{}", tx.tx_hash())?
342+
}
176343
};
177344
Ok(())
178345
}

0 commit comments

Comments
 (0)