alloy_zksync/contracts/common/
erc20.rs

1//! ZKsync-specific utilities related to ERC20 contracts.
2
3use ERC20::ERC20Instance;
4use alloy::network::Ethereum;
5use alloy::{
6    contract::Error,
7    dyn_abi::DynSolValue,
8    primitives::{Bytes, U256},
9};
10
11alloy::sol! {
12    /// ABI for an ERC20 contract.
13    #[sol(rpc)]
14    contract ERC20 {
15        function allowance(address owner, address spender) external view returns (uint256);
16        function approve(address spender, uint256 value) external returns (bool);
17
18        function name() public view virtual returns (string memory);
19        function symbol() public view virtual returns (string memory);
20        function decimals() public view virtual returns (uint8);
21    }
22}
23
24/// Encodes the token data for bridging an ERC20 token.
25///
26/// This function retrieves the name, symbol, and decimals of the ERC20 token
27/// and encodes them into a `Bytes` object for use in bridging operations.
28///
29/// # Arguments
30///
31/// * `erc20_contract` - An instance of the ERC20 contract.
32///
33/// # Returns
34///
35/// A `Result` containing the encoded token data as `Bytes` or an `Error`.
36/// ```
37pub(crate) async fn encode_token_data_for_bridge<P>(
38    erc20_contract: &ERC20Instance<P>,
39) -> Result<Bytes, Error>
40where
41    P: alloy::providers::Provider<Ethereum>,
42{
43    let erc20_name = erc20_contract.name().call().await?;
44    let erc20_symbol = erc20_contract.symbol().call().await?;
45    let erc20_decimals = erc20_contract.decimals().call().await?;
46
47    let token_data = Bytes::from(
48        DynSolValue::Tuple(vec![
49            DynSolValue::Bytes(DynSolValue::String(erc20_name).abi_encode()),
50            DynSolValue::Bytes(DynSolValue::String(erc20_symbol).abi_encode()),
51            DynSolValue::Bytes(DynSolValue::Uint(U256::from(erc20_decimals), 256).abi_encode()),
52        ])
53        .abi_encode_params(),
54    );
55
56    Ok(token_data)
57}