Skip to main content

cbrzn_ethers_core/utils/
mod.rs

1/// Utilities for launching a ganache-cli testnet instance
2#[cfg(not(target_arch = "wasm32"))]
3mod ganache;
4#[cfg(not(target_arch = "wasm32"))]
5pub use ganache::{Ganache, GanacheInstance};
6
7/// Utilities for launching a go-ethereum dev-mode instance
8#[cfg(not(target_arch = "wasm32"))]
9mod geth;
10#[cfg(not(target_arch = "wasm32"))]
11pub use geth::{Geth, GethInstance};
12
13/// Utilities for working with a `genesis.json` and other chain config structs.
14mod genesis;
15pub use genesis::{ChainConfig, CliqueConfig, EthashConfig, Genesis, GenesisAccount};
16
17/// Utilities for launching an anvil instance
18#[cfg(not(target_arch = "wasm32"))]
19mod anvil;
20#[cfg(not(target_arch = "wasm32"))]
21pub use anvil::{Anvil, AnvilInstance};
22
23/// Moonbeam utils
24pub mod moonbeam;
25
26mod hash;
27pub use hash::{hash_message, id, keccak256, serialize};
28
29mod units;
30use serde::{Deserialize, Deserializer};
31pub use units::Units;
32
33/// Re-export RLP
34pub use rlp;
35
36/// Re-export hex
37pub use hex;
38
39use crate::types::{Address, ParseI256Error, I256, U256, U64};
40use elliptic_curve::sec1::ToEncodedPoint;
41use ethabi::ethereum_types::FromDecStrErr;
42use k256::{ecdsa::SigningKey, PublicKey as K256PublicKey};
43use std::{
44    convert::{TryFrom, TryInto},
45    fmt,
46    str::FromStr,
47};
48use thiserror::Error;
49
50/// I256 overflows for numbers wider than 77 units.
51const OVERFLOW_I256_UNITS: usize = 77;
52/// U256 overflows for numbers wider than 78 units.
53const OVERFLOW_U256_UNITS: usize = 78;
54
55/// Re-export of serde-json
56#[doc(hidden)]
57pub mod __serde_json {
58    pub use serde_json::*;
59}
60
61#[derive(Error, Debug)]
62pub enum ConversionError {
63    #[error("Unknown units: {0}")]
64    UnrecognizedUnits(String),
65    #[error("bytes32 strings must not exceed 32 bytes in length")]
66    TextTooLong,
67    #[error(transparent)]
68    Utf8Error(#[from] std::str::Utf8Error),
69    #[error(transparent)]
70    InvalidFloat(#[from] std::num::ParseFloatError),
71    #[error(transparent)]
72    FromDecStrError(#[from] FromDecStrErr),
73    #[error("Overflow parsing string")]
74    ParseOverflow,
75    #[error(transparent)]
76    ParseI256Error(#[from] ParseI256Error),
77}
78
79/// 1 Ether = 1e18 Wei == 0x0de0b6b3a7640000 Wei
80pub const WEI_IN_ETHER: U256 = U256([0x0de0b6b3a7640000, 0x0, 0x0, 0x0]);
81
82/// The number of blocks from the past for which the fee rewards are fetched for fee estimation.
83pub const EIP1559_FEE_ESTIMATION_PAST_BLOCKS: u64 = 10;
84/// The default percentile of gas premiums that are fetched for fee estimation.
85pub const EIP1559_FEE_ESTIMATION_REWARD_PERCENTILE: f64 = 5.0;
86/// The default max priority fee per gas, used in case the base fee is within a threshold.
87pub const EIP1559_FEE_ESTIMATION_DEFAULT_PRIORITY_FEE: u64 = 3_000_000_000;
88/// The threshold for base fee below which we use the default priority fee, and beyond which we
89/// estimate an appropriate value for priority fee.
90pub const EIP1559_FEE_ESTIMATION_PRIORITY_FEE_TRIGGER: u64 = 100_000_000_000;
91/// The threshold max change/difference (in %) at which we will ignore the fee history values
92/// under it.
93pub const EIP1559_FEE_ESTIMATION_THRESHOLD_MAX_CHANGE: i64 = 200;
94
95/// This enum holds the numeric types that a possible to be returned by `parse_units` and
96/// that are taken by `format_units`.
97#[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq)]
98pub enum ParseUnits {
99    U256(U256),
100    I256(I256),
101}
102
103impl From<ParseUnits> for U256 {
104    fn from(n: ParseUnits) -> Self {
105        match n {
106            ParseUnits::U256(n) => n,
107            ParseUnits::I256(n) => n.into_raw(),
108        }
109    }
110}
111
112impl fmt::Display for ParseUnits {
113    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
114        match self {
115            ParseUnits::U256(val) => val.fmt(f),
116            ParseUnits::I256(val) => val.fmt(f),
117        }
118    }
119}
120
121macro_rules! construct_format_units_from {
122    ($( $t:ty[$convert:ident] ),*) => {
123        $(
124            impl From<$t> for ParseUnits {
125                fn from(num: $t) -> Self {
126                    Self::$convert(num.into())
127                }
128            }
129        )*
130    }
131}
132
133// Generate the From<T> code for the given numeric types below.
134construct_format_units_from! {
135    u8[U256], u16[U256], u32[U256], u64[U256], u128[U256], U256[U256], usize[U256],
136    i8[I256], i16[I256], i32[I256], i64[I256], i128[I256], I256[I256], isize[I256]
137}
138
139/// Format the output for the user which prefer to see values
140/// in ether (instead of wei)
141///
142/// Divides the input by 1e18
143pub fn format_ether<T: Into<U256>>(amount: T) -> U256 {
144    amount.into() / WEI_IN_ETHER
145}
146
147/// Divides the provided amount with 10^{units} provided.
148///
149/// ```
150/// use ethers_core::{types::U256, utils::format_units};
151///
152/// let eth = format_units(1395633240123456000_u128, "ether").unwrap();
153/// assert_eq!(eth.parse::<f64>().unwrap(), 1.395633240123456);
154///
155/// let eth = format_units(U256::from_dec_str("1395633240123456000").unwrap(), "ether").unwrap();
156/// assert_eq!(eth.parse::<f64>().unwrap(), 1.395633240123456);
157///
158/// let eth = format_units(U256::from_dec_str("1395633240123456789").unwrap(), "ether").unwrap();
159/// assert_eq!(eth, "1.395633240123456789");
160///
161/// let eth = format_units(i64::MIN, "gwei").unwrap();
162/// assert_eq!(eth, "-9223372036.854775808");
163///
164/// let eth = format_units(i128::MIN, 36).unwrap();
165/// assert_eq!(eth, "-170.141183460469231731687303715884105728");
166/// ```
167pub fn format_units<T, K>(amount: T, units: K) -> Result<String, ConversionError>
168where
169    T: Into<ParseUnits>,
170    K: TryInto<Units, Error = ConversionError>,
171{
172    let units: usize = units.try_into()?.into();
173    let amount = amount.into();
174
175    match amount {
176        // 2**256 ~= 1.16e77
177        ParseUnits::U256(_) if units >= OVERFLOW_U256_UNITS => {
178            return Err(ConversionError::ParseOverflow)
179        }
180        // 2**255 ~= 5.79e76
181        ParseUnits::I256(_) if units >= OVERFLOW_I256_UNITS => {
182            return Err(ConversionError::ParseOverflow)
183        }
184        _ => {}
185    };
186    let exp10 = U256::exp10(units);
187
188    // `decimals` are formatted twice because U256 does not support alignment (`:0>width`).
189    match amount {
190        ParseUnits::U256(amount) => {
191            let integer = amount / exp10;
192            let decimals = (amount % exp10).to_string();
193            Ok(format!("{integer}.{decimals:0>units$}"))
194        }
195        ParseUnits::I256(amount) => {
196            let exp10 = I256::from_raw(exp10);
197            let sign = if amount.is_negative() { "-" } else { "" };
198            let integer = (amount / exp10).twos_complement();
199            let decimals = ((amount % exp10).twos_complement()).to_string();
200            Ok(format!("{sign}{integer}.{decimals:0>units$}"))
201        }
202    }
203}
204
205/// Converts the input to a U256 and converts from Ether to Wei.
206///
207/// ```
208/// use ethers_core::{types::U256, utils::{parse_ether, WEI_IN_ETHER}};
209///
210/// let eth = U256::from(WEI_IN_ETHER);
211/// assert_eq!(eth, parse_ether(1u8).unwrap());
212/// assert_eq!(eth, parse_ether(1usize).unwrap());
213/// assert_eq!(eth, parse_ether("1").unwrap());
214/// ```
215pub fn parse_ether<S: ToString>(eth: S) -> Result<U256, ConversionError> {
216    Ok(parse_units(eth, "ether")?.into())
217}
218
219/// Multiplies the provided amount with 10^{units} provided.
220///
221/// ```
222/// use ethers_core::{types::U256, utils::parse_units};
223/// let amount_in_eth = U256::from_dec_str("15230001000000000000").unwrap();
224/// let amount_in_gwei = U256::from_dec_str("15230001000").unwrap();
225/// let amount_in_wei = U256::from_dec_str("15230001000").unwrap();
226/// assert_eq!(amount_in_eth, parse_units("15.230001000000000000", "ether").unwrap().into());
227/// assert_eq!(amount_in_gwei, parse_units("15.230001000000000000", "gwei").unwrap().into());
228/// assert_eq!(amount_in_wei, parse_units("15230001000", "wei").unwrap().into());
229/// ```
230/// Example of trying to parse decimal WEI, which should fail, as WEI is the smallest
231/// ETH denominator. 1 ETH = 10^18 WEI.
232/// ```should_panic
233/// use ethers_core::{types::U256, utils::parse_units};
234/// let amount_in_wei = U256::from_dec_str("15230001000").unwrap();
235/// assert_eq!(amount_in_wei, parse_units("15.230001000000000000", "wei").unwrap().into());
236/// ```
237pub fn parse_units<K, S>(amount: S, units: K) -> Result<ParseUnits, ConversionError>
238where
239    S: ToString,
240    K: TryInto<Units, Error = ConversionError> + Copy,
241{
242    let exponent: u32 = units.try_into()?.as_num();
243    let mut amount_str = amount.to_string().replace('_', "");
244    let negative = amount_str.chars().next().unwrap_or_default() == '-';
245    let dec_len = if let Some(di) = amount_str.find('.') {
246        amount_str.remove(di);
247        amount_str[di..].len() as u32
248    } else {
249        0
250    };
251
252    if dec_len > exponent {
253        // Truncate the decimal part if it is longer than the exponent
254        let amount_str = &amount_str[..(amount_str.len() - (dec_len - exponent) as usize)];
255        if negative {
256            // Edge case: We have removed the entire number and only the negative sign is left.
257            //            Return 0 as a I256 given the input was signed.
258            if amount_str == "-" {
259                Ok(ParseUnits::I256(I256::zero()))
260            } else {
261                Ok(ParseUnits::I256(I256::from_dec_str(amount_str)?))
262            }
263        } else {
264            Ok(ParseUnits::U256(U256::from_dec_str(amount_str)?))
265        }
266    } else if negative {
267        // Edge case: Only a negative sign was given, return 0 as a I256 given the input was signed.
268        if amount_str == "-" {
269            Ok(ParseUnits::I256(I256::zero()))
270        } else {
271            let mut n = I256::from_dec_str(&amount_str)?;
272            n *= I256::from(10)
273                .checked_pow(exponent - dec_len)
274                .ok_or(ConversionError::ParseOverflow)?;
275            Ok(ParseUnits::I256(n))
276        }
277    } else {
278        let mut a_uint = U256::from_dec_str(&amount_str)?;
279        a_uint *= U256::from(10)
280            .checked_pow(U256::from(exponent - dec_len))
281            .ok_or(ConversionError::ParseOverflow)?;
282        Ok(ParseUnits::U256(a_uint))
283    }
284}
285
286/// The address for an Ethereum contract is deterministically computed from the
287/// address of its creator (sender) and how many transactions the creator has
288/// sent (nonce). The sender and nonce are RLP encoded and then hashed with Keccak-256.
289pub fn get_contract_address(sender: impl Into<Address>, nonce: impl Into<U256>) -> Address {
290    let mut stream = rlp::RlpStream::new();
291    stream.begin_list(2);
292    stream.append(&sender.into());
293    stream.append(&nonce.into());
294
295    let hash = keccak256(&stream.out());
296
297    let mut bytes = [0u8; 20];
298    bytes.copy_from_slice(&hash[12..]);
299    Address::from(bytes)
300}
301
302/// Returns the CREATE2 address of a smart contract as specified in
303/// [EIP1014](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1014.md)
304///
305/// keccak256( 0xff ++ senderAddress ++ salt ++ keccak256(init_code))[12..]
306pub fn get_create2_address(
307    from: impl Into<Address>,
308    salt: impl AsRef<[u8]>,
309    init_code: impl AsRef<[u8]>,
310) -> Address {
311    let init_code_hash = keccak256(init_code.as_ref());
312    get_create2_address_from_hash(from, salt, init_code_hash)
313}
314
315/// Returns the CREATE2 address of a smart contract as specified in
316/// [EIP1014](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1014.md),
317/// taking the pre-computed hash of the init code as input.
318///
319/// keccak256( 0xff ++ senderAddress ++ salt ++ keccak256(init_code))[12..]
320///
321/// # Example
322///
323/// Calculate the address of a UniswapV3 pool.
324///
325/// ```
326/// use ethers_core::{
327///     abi,
328///     abi::Token,
329///     types::{Address, Bytes, U256},
330///     utils::{get_create2_address_from_hash, keccak256},
331/// };
332///
333/// let init_code_hash = hex::decode("e34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54").unwrap();
334/// let factory: Address = "0x1F98431c8aD98523631AE4a59f267346ea31F984"
335///     .parse()
336///     .unwrap();
337/// let token0: Address = "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
338///     .parse()
339///     .unwrap();
340/// let token1: Address = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
341///     .parse()
342///     .unwrap();
343/// let fee = U256::from(500_u64);
344///
345/// // abi.encode(token0 as address, token1 as address, fee as uint256)
346/// let input = abi::encode(&[
347///     Token::Address(token0),
348///     Token::Address(token1),
349///     Token::Uint(fee),
350/// ]);
351///
352/// // keccak256(abi.encode(token0, token1, fee))
353/// let salt = keccak256(&input);
354/// let pool_address = get_create2_address_from_hash(factory, salt, init_code_hash);
355///
356/// assert_eq!(
357///     pool_address,
358///     "0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640" // USDC/ETH pool address
359///         .parse()
360///         .unwrap()
361/// );
362/// ```
363pub fn get_create2_address_from_hash(
364    from: impl Into<Address>,
365    salt: impl AsRef<[u8]>,
366    init_code_hash: impl AsRef<[u8]>,
367) -> Address {
368    let from = from.into();
369    let salt = salt.as_ref();
370    let init_code_hash = init_code_hash.as_ref();
371
372    let mut bytes = Vec::with_capacity(1 + 20 + salt.len() + init_code_hash.len());
373    bytes.push(0xff);
374    bytes.extend_from_slice(from.as_bytes());
375    bytes.extend_from_slice(salt);
376    bytes.extend_from_slice(init_code_hash);
377
378    let hash = keccak256(bytes);
379
380    let mut bytes = [0u8; 20];
381    bytes.copy_from_slice(&hash[12..]);
382    Address::from(bytes)
383}
384
385/// Converts a K256 SigningKey to an Ethereum Address
386pub fn secret_key_to_address(secret_key: &SigningKey) -> Address {
387    let public_key = K256PublicKey::from(&secret_key.verifying_key());
388    let public_key = public_key.to_encoded_point(/* compress = */ false);
389    let public_key = public_key.as_bytes();
390    debug_assert_eq!(public_key[0], 0x04);
391    let hash = keccak256(&public_key[1..]);
392
393    let mut bytes = [0u8; 20];
394    bytes.copy_from_slice(&hash[12..]);
395    Address::from(bytes)
396}
397
398/// Encodes an Ethereum address to its [EIP-55] checksum.
399///
400/// You can optionally specify an [EIP-155 chain ID] to encode the address using the [EIP-1191]
401/// extension.
402///
403/// [EIP-55]: https://eips.ethereum.org/EIPS/eip-55
404/// [EIP-155 chain ID]: https://eips.ethereum.org/EIPS/eip-155
405/// [EIP-1191]: https://eips.ethereum.org/EIPS/eip-1191
406pub fn to_checksum(addr: &Address, chain_id: Option<u8>) -> String {
407    let prefixed_addr = match chain_id {
408        Some(chain_id) => format!("{chain_id}0x{addr:x}"),
409        None => format!("{addr:x}"),
410    };
411    let hash = hex::encode(keccak256(prefixed_addr));
412    let hash = hash.as_bytes();
413
414    let addr_hex = hex::encode(addr.as_bytes());
415    let addr_hex = addr_hex.as_bytes();
416
417    addr_hex.iter().zip(hash).fold("0x".to_owned(), |mut encoded, (addr, hash)| {
418        encoded.push(if *hash >= 56 {
419            addr.to_ascii_uppercase() as char
420        } else {
421            addr.to_ascii_lowercase() as char
422        });
423        encoded
424    })
425}
426
427/// Returns a bytes32 string representation of text. If the length of text exceeds 32 bytes,
428/// an error is returned.
429pub fn format_bytes32_string(text: &str) -> Result<[u8; 32], ConversionError> {
430    let str_bytes: &[u8] = text.as_bytes();
431    if str_bytes.len() > 32 {
432        return Err(ConversionError::TextTooLong)
433    }
434
435    let mut bytes32: [u8; 32] = [0u8; 32];
436    bytes32[..str_bytes.len()].copy_from_slice(str_bytes);
437
438    Ok(bytes32)
439}
440
441/// Returns the decoded string represented by the bytes32 encoded data.
442pub fn parse_bytes32_string(bytes: &[u8; 32]) -> Result<&str, ConversionError> {
443    let mut length = 0;
444    while length < 32 && bytes[length] != 0 {
445        length += 1;
446    }
447
448    Ok(std::str::from_utf8(&bytes[..length])?)
449}
450
451/// The default EIP-1559 fee estimator which is based on the work by [MyCrypto](https://github.com/MyCryptoHQ/MyCrypto/blob/master/src/services/ApiService/Gas/eip1559.ts)
452pub fn eip1559_default_estimator(base_fee_per_gas: U256, rewards: Vec<Vec<U256>>) -> (U256, U256) {
453    let max_priority_fee_per_gas =
454        if base_fee_per_gas < U256::from(EIP1559_FEE_ESTIMATION_PRIORITY_FEE_TRIGGER) {
455            U256::from(EIP1559_FEE_ESTIMATION_DEFAULT_PRIORITY_FEE)
456        } else {
457            std::cmp::max(
458                estimate_priority_fee(rewards),
459                U256::from(EIP1559_FEE_ESTIMATION_DEFAULT_PRIORITY_FEE),
460            )
461        };
462    let potential_max_fee = base_fee_surged(base_fee_per_gas);
463    let max_fee_per_gas = if max_priority_fee_per_gas > potential_max_fee {
464        max_priority_fee_per_gas + potential_max_fee
465    } else {
466        potential_max_fee
467    };
468    (max_fee_per_gas, max_priority_fee_per_gas)
469}
470
471/// Deserializes the input into a U256, accepting both 0x-prefixed hex and decimal strings with
472/// arbitrary precision, defined by serde_json's [`Number`](serde_json::Number).
473pub fn from_int_or_hex<'de, D>(deserializer: D) -> Result<U256, D::Error>
474where
475    D: Deserializer<'de>,
476{
477    #[derive(Deserialize)]
478    #[serde(untagged)]
479    enum IntOrHex {
480        Int(serde_json::Number),
481        Hex(String),
482    }
483
484    match IntOrHex::deserialize(deserializer)? {
485        IntOrHex::Hex(s) => U256::from_str(s.as_str()).map_err(serde::de::Error::custom),
486        IntOrHex::Int(n) => U256::from_dec_str(&n.to_string()).map_err(serde::de::Error::custom),
487    }
488}
489
490/// Deserializes the input into a U64, accepting both 0x-prefixed hex and decimal strings with
491/// arbitrary precision, defined by serde_json's [`Number`](serde_json::Number).
492pub fn from_u64_or_hex<'de, D>(deserializer: D) -> Result<U64, D::Error>
493where
494    D: Deserializer<'de>,
495{
496    #[derive(Deserialize)]
497    #[serde(untagged)]
498    enum IntOrHex {
499        Int(serde_json::Number),
500        Hex(String),
501    }
502
503    match IntOrHex::deserialize(deserializer)? {
504        IntOrHex::Hex(s) => U64::from_str(s.as_str()).map_err(serde::de::Error::custom),
505        IntOrHex::Int(n) => U64::from_dec_str(&n.to_string()).map_err(serde::de::Error::custom),
506    }
507}
508
509/// Deserializes the input into an `Option<U256>`, using [`from_int_or_hex`] to deserialize the
510/// inner value.
511pub fn from_int_or_hex_opt<'de, D>(deserializer: D) -> Result<Option<U256>, D::Error>
512where
513    D: Deserializer<'de>,
514{
515    Ok(Some(from_int_or_hex(deserializer)?))
516}
517
518/// Deserializes the input into an `Option<u64>`, using [`from_u64_or_hex`] to deserialize the
519/// inner value.
520pub fn from_u64_or_hex_opt<'de, D>(deserializer: D) -> Result<Option<u64>, D::Error>
521where
522    D: Deserializer<'de>,
523{
524    Ok(Some(from_u64_or_hex(deserializer)?.as_u64()))
525}
526
527fn estimate_priority_fee(rewards: Vec<Vec<U256>>) -> U256 {
528    let mut rewards: Vec<U256> =
529        rewards.iter().map(|r| r[0]).filter(|r| *r > U256::zero()).collect();
530    if rewards.is_empty() {
531        return U256::zero()
532    }
533    if rewards.len() == 1 {
534        return rewards[0]
535    }
536    // Sort the rewards as we will eventually take the median.
537    rewards.sort();
538
539    // A copy of the same vector is created for convenience to calculate percentage change
540    // between subsequent fee values.
541    let mut rewards_copy = rewards.clone();
542    rewards_copy.rotate_left(1);
543
544    let mut percentage_change: Vec<I256> = rewards
545        .iter()
546        .zip(rewards_copy.iter())
547        .map(|(a, b)| {
548            let a = I256::try_from(*a).expect("priority fee overflow");
549            let b = I256::try_from(*b).expect("priority fee overflow");
550            ((b - a) * 100) / a
551        })
552        .collect();
553    percentage_change.pop();
554
555    // Fetch the max of the percentage change, and that element's index.
556    let max_change = percentage_change.iter().max().unwrap();
557    let max_change_index = percentage_change.iter().position(|&c| c == *max_change).unwrap();
558
559    // If we encountered a big change in fees at a certain position, then consider only
560    // the values >= it.
561    let values = if *max_change >= EIP1559_FEE_ESTIMATION_THRESHOLD_MAX_CHANGE.into() &&
562        (max_change_index >= (rewards.len() / 2))
563    {
564        rewards[max_change_index..].to_vec()
565    } else {
566        rewards
567    };
568
569    // Return the median.
570    values[values.len() / 2]
571}
572
573fn base_fee_surged(base_fee_per_gas: U256) -> U256 {
574    if base_fee_per_gas <= U256::from(40_000_000_000u64) {
575        base_fee_per_gas * 2
576    } else if base_fee_per_gas <= U256::from(100_000_000_000u64) {
577        base_fee_per_gas * 16 / 10
578    } else if base_fee_per_gas <= U256::from(200_000_000_000u64) {
579        base_fee_per_gas * 14 / 10
580    } else {
581        base_fee_per_gas * 12 / 10
582    }
583}
584
585/// A bit of hack to find an unused TCP port.
586///
587/// Does not guarantee that the given port is unused after the function exists, just that it was
588/// unused before the function started (i.e., it does not reserve a port).
589#[cfg(not(target_arch = "wasm32"))]
590pub(crate) fn unused_port() -> u16 {
591    let listener = std::net::TcpListener::bind("127.0.0.1:0")
592        .expect("Failed to create TCP listener to find unused port");
593
594    let local_addr =
595        listener.local_addr().expect("Failed to read TCP listener local_addr to find unused port");
596    local_addr.port()
597}
598
599#[cfg(test)]
600mod tests {
601    use super::*;
602    use hex_literal::hex;
603
604    #[test]
605    fn wei_in_ether() {
606        assert_eq!(WEI_IN_ETHER.as_u64(), 1e18 as u64);
607    }
608
609    #[test]
610    fn test_format_units_unsigned() {
611        let gwei_in_ether = format_units(WEI_IN_ETHER, 9).unwrap();
612        assert_eq!(gwei_in_ether.parse::<f64>().unwrap() as u64, 1e9 as u64);
613
614        let eth = format_units(WEI_IN_ETHER, "ether").unwrap();
615        assert_eq!(eth.parse::<f64>().unwrap() as u64, 1);
616
617        let eth = format_units(1395633240123456000_u128, "ether").unwrap();
618        assert_eq!(eth.parse::<f64>().unwrap(), 1.395633240123456);
619
620        let eth =
621            format_units(U256::from_dec_str("1395633240123456000").unwrap(), "ether").unwrap();
622        assert_eq!(eth.parse::<f64>().unwrap(), 1.395633240123456);
623
624        let eth =
625            format_units(U256::from_dec_str("1395633240123456789").unwrap(), "ether").unwrap();
626        assert_eq!(eth, "1.395633240123456789");
627
628        let eth =
629            format_units(U256::from_dec_str("1005633240123456789").unwrap(), "ether").unwrap();
630        assert_eq!(eth, "1.005633240123456789");
631
632        let eth = format_units(u8::MAX, 4).unwrap();
633        assert_eq!(eth, "0.0255");
634
635        let eth = format_units(u16::MAX, "ether").unwrap();
636        assert_eq!(eth, "0.000000000000065535");
637
638        // Note: This covers usize on 32 bit systems.
639        let eth = format_units(u32::MAX, 18).unwrap();
640        assert_eq!(eth, "0.000000004294967295");
641
642        // Note: This covers usize on 64 bit systems.
643        let eth = format_units(u64::MAX, "gwei").unwrap();
644        assert_eq!(eth, "18446744073.709551615");
645
646        let eth = format_units(u128::MAX, 36).unwrap();
647        assert_eq!(eth, "340.282366920938463463374607431768211455");
648
649        let eth = format_units(U256::MAX, 77).unwrap();
650        assert_eq!(
651            eth,
652            "1.15792089237316195423570985008687907853269984665640564039457584007913129639935"
653        );
654
655        let err = format_units(U256::MAX, 78).unwrap_err();
656        assert!(matches!(err, ConversionError::ParseOverflow));
657    }
658
659    #[test]
660    fn test_format_units_signed() {
661        let eth =
662            format_units(I256::from_dec_str("-1395633240123456000").unwrap(), "ether").unwrap();
663        assert_eq!(eth.parse::<f64>().unwrap(), -1.395633240123456);
664
665        let eth =
666            format_units(I256::from_dec_str("-1395633240123456789").unwrap(), "ether").unwrap();
667        assert_eq!(eth, "-1.395633240123456789");
668
669        let eth =
670            format_units(I256::from_dec_str("1005633240123456789").unwrap(), "ether").unwrap();
671        assert_eq!(eth, "1.005633240123456789");
672
673        let eth = format_units(i8::MIN, 4).unwrap();
674        assert_eq!(eth, "-0.0128");
675        assert_eq!(eth.parse::<f64>().unwrap(), -0.0128_f64);
676
677        let eth = format_units(i8::MAX, 4).unwrap();
678        assert_eq!(eth, "0.0127");
679        assert_eq!(eth.parse::<f64>().unwrap(), 0.0127);
680
681        let eth = format_units(i16::MIN, "ether").unwrap();
682        assert_eq!(eth, "-0.000000000000032768");
683
684        // Note: This covers isize on 32 bit systems.
685        let eth = format_units(i32::MIN, 18).unwrap();
686        assert_eq!(eth, "-0.000000002147483648");
687
688        // Note: This covers isize on 64 bit systems.
689        let eth = format_units(i64::MIN, "gwei").unwrap();
690        assert_eq!(eth, "-9223372036.854775808");
691
692        let eth = format_units(i128::MIN, 36).unwrap();
693        assert_eq!(eth, "-170.141183460469231731687303715884105728");
694
695        let eth = format_units(I256::MIN, 76).unwrap();
696        assert_eq!(
697            eth,
698            "-5.7896044618658097711785492504343953926634992332820282019728792003956564819968"
699        );
700
701        let err = format_units(I256::MIN, 77).unwrap_err();
702        assert!(matches!(err, ConversionError::ParseOverflow));
703    }
704
705    #[test]
706    fn parse_large_units() {
707        let decimals = 27u32;
708        let val = "10.55";
709
710        let n: U256 = parse_units(val, decimals).unwrap().into();
711        assert_eq!(n.to_string(), "10550000000000000000000000000");
712    }
713
714    #[test]
715    fn test_parse_units() {
716        let gwei: U256 = parse_units(1.5, 9).unwrap().into();
717        assert_eq!(gwei.as_u64(), 15e8 as u64);
718
719        let token: U256 = parse_units(1163.56926418, 8).unwrap().into();
720        assert_eq!(token.as_u64(), 116356926418);
721
722        let eth_dec_float: U256 = parse_units(1.39563324, "ether").unwrap().into();
723        assert_eq!(eth_dec_float, U256::from_dec_str("1395633240000000000").unwrap());
724
725        let eth_dec_string: U256 = parse_units("1.39563324", "ether").unwrap().into();
726        assert_eq!(eth_dec_string, U256::from_dec_str("1395633240000000000").unwrap());
727
728        let eth: U256 = parse_units(1, "ether").unwrap().into();
729        assert_eq!(eth, WEI_IN_ETHER);
730
731        let val: U256 = parse_units("2.3", "ether").unwrap().into();
732        assert_eq!(val, U256::from_dec_str("2300000000000000000").unwrap());
733
734        let n: U256 = parse_units(".2", 2).unwrap().into();
735        assert_eq!(n, U256::from(20), "leading dot");
736
737        let n: U256 = parse_units("333.21", 2).unwrap().into();
738        assert_eq!(n, U256::from(33321), "trailing dot");
739
740        let n: U256 = parse_units("98766", 16).unwrap().into();
741        assert_eq!(n, U256::from_dec_str("987660000000000000000").unwrap(), "no dot");
742
743        let n: U256 = parse_units("3_3_0", 3).unwrap().into();
744        assert_eq!(n, U256::from(330000), "underscore");
745
746        let n: U256 = parse_units("330", 0).unwrap().into();
747        assert_eq!(n, U256::from(330), "zero decimals");
748
749        let n: U256 = parse_units(".1234", 3).unwrap().into();
750        assert_eq!(n, U256::from(123), "truncate too many decimals");
751
752        assert!(parse_units("1", 80).is_err(), "overflow");
753        assert!(parse_units("1", -1).is_err(), "neg units");
754
755        let two_e30 = U256::from(2) * U256([0x4674edea40000000, 0xc9f2c9cd0, 0x0, 0x0]);
756        let n: U256 = parse_units("2", 30).unwrap().into();
757        assert_eq!(n, two_e30, "2e30");
758
759        let n: U256 = parse_units(".33_319_2", 0).unwrap().into();
760        assert_eq!(n, U256::zero(), "mix");
761
762        let n: U256 = parse_units("", 3).unwrap().into();
763        assert_eq!(n, U256::zero(), "empty");
764    }
765
766    #[test]
767    fn test_signed_parse_units() {
768        let gwei: I256 = parse_units(-1.5, 9).unwrap().into();
769        assert_eq!(gwei.as_i64(), -15e8 as i64);
770
771        let token: I256 = parse_units(-1163.56926418, 8).unwrap().into();
772        assert_eq!(token.as_i64(), -116356926418);
773
774        let eth_dec_float: I256 = parse_units(-1.39563324, "ether").unwrap().into();
775        assert_eq!(eth_dec_float, I256::from_dec_str("-1395633240000000000").unwrap());
776
777        let eth_dec_string: I256 = parse_units("-1.39563324", "ether").unwrap().into();
778        assert_eq!(eth_dec_string, I256::from_dec_str("-1395633240000000000").unwrap());
779
780        let eth: I256 = parse_units(-1, "ether").unwrap().into();
781        assert_eq!(eth, I256::from_raw(WEI_IN_ETHER) * I256::minus_one());
782
783        let val: I256 = parse_units("-2.3", "ether").unwrap().into();
784        assert_eq!(val, I256::from_dec_str("-2300000000000000000").unwrap());
785
786        let n: I256 = parse_units("-.2", 2).unwrap().into();
787        assert_eq!(n, I256::from(-20), "leading dot");
788
789        let n: I256 = parse_units("-333.21", 2).unwrap().into();
790        assert_eq!(n, I256::from(-33321), "trailing dot");
791
792        let n: I256 = parse_units("-98766", 16).unwrap().into();
793        assert_eq!(n, I256::from_dec_str("-987660000000000000000").unwrap(), "no dot");
794
795        let n: I256 = parse_units("-3_3_0", 3).unwrap().into();
796        assert_eq!(n, I256::from(-330000), "underscore");
797
798        let n: I256 = parse_units("-330", 0).unwrap().into();
799        assert_eq!(n, I256::from(-330), "zero decimals");
800
801        let n: I256 = parse_units("-.1234", 3).unwrap().into();
802        assert_eq!(n, I256::from(-123), "truncate too many decimals");
803
804        assert!(parse_units("-1", 80).is_err(), "overflow");
805
806        let two_e30 =
807            I256::from(-2) * I256::from_raw(U256([0x4674edea40000000, 0xc9f2c9cd0, 0x0, 0x0]));
808        let n: I256 = parse_units("-2", 30).unwrap().into();
809        assert_eq!(n, two_e30, "-2e30");
810
811        let n: I256 = parse_units("-.33_319_2", 0).unwrap().into();
812        assert_eq!(n, I256::zero(), "mix");
813
814        let n: I256 = parse_units("-", 3).unwrap().into();
815        assert_eq!(n, I256::zero(), "empty");
816    }
817
818    #[test]
819    fn addr_checksum() {
820        let addr_list = vec![
821            // mainnet
822            (
823                None,
824                "27b1fdb04752bbc536007a920d24acb045561c26",
825                "0x27b1fdb04752bbc536007a920d24acb045561c26",
826            ),
827            (
828                None,
829                "3599689e6292b81b2d85451025146515070129bb",
830                "0x3599689E6292b81B2d85451025146515070129Bb",
831            ),
832            (
833                None,
834                "42712d45473476b98452f434e72461577d686318",
835                "0x42712D45473476b98452f434e72461577D686318",
836            ),
837            (
838                None,
839                "52908400098527886e0f7030069857d2e4169ee7",
840                "0x52908400098527886E0F7030069857D2E4169EE7",
841            ),
842            (
843                None,
844                "5aaeb6053f3e94c9b9a09f33669435e7ef1beaed",
845                "0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed",
846            ),
847            (
848                None,
849                "6549f4939460de12611948b3f82b88c3c8975323",
850                "0x6549f4939460DE12611948b3f82b88C3C8975323",
851            ),
852            (
853                None,
854                "66f9664f97f2b50f62d13ea064982f936de76657",
855                "0x66f9664f97F2b50F62D13eA064982f936dE76657",
856            ),
857            (
858                None,
859                "88021160c5c792225e4e5452585947470010289d",
860                "0x88021160C5C792225E4E5452585947470010289D",
861            ),
862            // rsk mainnet
863            (
864                Some(30),
865                "27b1fdb04752bbc536007a920d24acb045561c26",
866                "0x27b1FdB04752BBc536007A920D24ACB045561c26",
867            ),
868            (
869                Some(30),
870                "3599689e6292b81b2d85451025146515070129bb",
871                "0x3599689E6292B81B2D85451025146515070129Bb",
872            ),
873            (
874                Some(30),
875                "42712d45473476b98452f434e72461577d686318",
876                "0x42712D45473476B98452f434E72461577d686318",
877            ),
878            (
879                Some(30),
880                "52908400098527886e0f7030069857d2e4169ee7",
881                "0x52908400098527886E0F7030069857D2E4169ee7",
882            ),
883            (
884                Some(30),
885                "5aaeb6053f3e94c9b9a09f33669435e7ef1beaed",
886                "0x5aaEB6053f3e94c9b9a09f33669435E7ef1bEAeD",
887            ),
888            (
889                Some(30),
890                "6549f4939460de12611948b3f82b88c3c8975323",
891                "0x6549F4939460DE12611948B3F82B88C3C8975323",
892            ),
893            (
894                Some(30),
895                "66f9664f97f2b50f62d13ea064982f936de76657",
896                "0x66F9664f97f2B50F62d13EA064982F936de76657",
897            ),
898        ];
899
900        for (chain_id, addr, checksummed_addr) in addr_list {
901            let addr = addr.parse::<Address>().unwrap();
902            assert_eq!(to_checksum(&addr, chain_id), String::from(checksummed_addr));
903        }
904    }
905
906    #[test]
907    fn contract_address() {
908        // http://ethereum.stackexchange.com/questions/760/how-is-the-address-of-an-ethereum-contract-computed
909        let from = "6ac7ea33f8831ea9dcc53393aaa88b25a785dbf0".parse::<Address>().unwrap();
910        for (nonce, expected) in [
911            "cd234a471b72ba2f1ccf0a70fcaba648a5eecd8d",
912            "343c43a37d37dff08ae8c4a11544c718abb4fcf8",
913            "f778b86fa74e846c4f0a1fbd1335fe81c00a0c91",
914            "fffd933a0bc612844eaf0c6fe3e5b8e9b6c1d19c",
915        ]
916        .iter()
917        .enumerate()
918        {
919            let address = get_contract_address(from, nonce);
920            assert_eq!(address, expected.parse::<Address>().unwrap());
921        }
922    }
923
924    #[test]
925    // Test vectors from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1014.md#examples
926    fn create2_address() {
927        for (from, salt, init_code, expected) in &[
928            (
929                "0000000000000000000000000000000000000000",
930                "0000000000000000000000000000000000000000000000000000000000000000",
931                "00",
932                "4D1A2e2bB4F88F0250f26Ffff098B0b30B26BF38",
933            ),
934            (
935                "deadbeef00000000000000000000000000000000",
936                "0000000000000000000000000000000000000000000000000000000000000000",
937                "00",
938                "B928f69Bb1D91Cd65274e3c79d8986362984fDA3",
939            ),
940            (
941                "deadbeef00000000000000000000000000000000",
942                "000000000000000000000000feed000000000000000000000000000000000000",
943                "00",
944                "D04116cDd17beBE565EB2422F2497E06cC1C9833",
945            ),
946            (
947                "0000000000000000000000000000000000000000",
948                "0000000000000000000000000000000000000000000000000000000000000000",
949                "deadbeef",
950                "70f2b2914A2a4b783FaEFb75f459A580616Fcb5e",
951            ),
952            (
953                "00000000000000000000000000000000deadbeef",
954                "00000000000000000000000000000000000000000000000000000000cafebabe",
955                "deadbeef",
956                "60f3f640a8508fC6a86d45DF051962668E1e8AC7",
957            ),
958            (
959                "00000000000000000000000000000000deadbeef",
960                "00000000000000000000000000000000000000000000000000000000cafebabe",
961                "deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef",
962                "1d8bfDC5D46DC4f61D6b6115972536eBE6A8854C",
963            ),
964            (
965                "0000000000000000000000000000000000000000",
966                "0000000000000000000000000000000000000000000000000000000000000000",
967                "",
968                "E33C0C7F7df4809055C3ebA6c09CFe4BaF1BD9e0",
969            ),
970        ] {
971            // get_create2_address()
972            let from = from.parse::<Address>().unwrap();
973            let salt = hex::decode(salt).unwrap();
974            let init_code = hex::decode(init_code).unwrap();
975            let expected = expected.parse::<Address>().unwrap();
976            assert_eq!(expected, get_create2_address(from, salt.clone(), init_code.clone()));
977
978            // get_create2_address_from_hash()
979            let init_code_hash = keccak256(init_code).to_vec();
980            assert_eq!(expected, get_create2_address_from_hash(from, salt, init_code_hash))
981        }
982    }
983
984    #[test]
985    fn bytes32_string_parsing() {
986        let text_bytes_list = vec![
987            ("", hex!("0000000000000000000000000000000000000000000000000000000000000000")),
988            ("A", hex!("4100000000000000000000000000000000000000000000000000000000000000")),
989            (
990                "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345",
991                hex!("4142434445464748494a4b4c4d4e4f505152535455565758595a303132333435"),
992            ),
993            (
994                "!@#$%^&*(),./;'[]",
995                hex!("21402324255e262a28292c2e2f3b275b5d000000000000000000000000000000"),
996            ),
997        ];
998
999        for (text, bytes) in text_bytes_list {
1000            assert_eq!(text, parse_bytes32_string(&bytes).unwrap());
1001        }
1002    }
1003
1004    #[test]
1005    fn bytes32_string_formatting() {
1006        let text_bytes_list = vec![
1007            ("", hex!("0000000000000000000000000000000000000000000000000000000000000000")),
1008            ("A", hex!("4100000000000000000000000000000000000000000000000000000000000000")),
1009            (
1010                "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345",
1011                hex!("4142434445464748494a4b4c4d4e4f505152535455565758595a303132333435"),
1012            ),
1013            (
1014                "!@#$%^&*(),./;'[]",
1015                hex!("21402324255e262a28292c2e2f3b275b5d000000000000000000000000000000"),
1016            ),
1017        ];
1018
1019        for (text, bytes) in text_bytes_list {
1020            assert_eq!(bytes, format_bytes32_string(text).unwrap());
1021        }
1022    }
1023
1024    #[test]
1025    fn bytes32_string_formatting_too_long() {
1026        assert!(matches!(
1027            format_bytes32_string("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456").unwrap_err(),
1028            ConversionError::TextTooLong
1029        ));
1030    }
1031
1032    #[test]
1033    fn test_eip1559_default_estimator() {
1034        // If the base fee is below the triggering base fee, we should get the default priority fee
1035        // with the base fee surged.
1036        let base_fee_per_gas = U256::from(EIP1559_FEE_ESTIMATION_PRIORITY_FEE_TRIGGER) - 1;
1037        let rewards: Vec<Vec<U256>> = vec![vec![]];
1038        let (base_fee, priority_fee) = eip1559_default_estimator(base_fee_per_gas, rewards);
1039        assert_eq!(priority_fee, U256::from(EIP1559_FEE_ESTIMATION_DEFAULT_PRIORITY_FEE));
1040        assert_eq!(base_fee, base_fee_surged(base_fee_per_gas));
1041
1042        // If the base fee is above the triggering base fee, we calculate the priority fee using
1043        // the fee history (rewards).
1044        let base_fee_per_gas = U256::from(EIP1559_FEE_ESTIMATION_PRIORITY_FEE_TRIGGER) + 1;
1045        let rewards: Vec<Vec<U256>> = vec![
1046            vec![100_000_000_000u64.into()],
1047            vec![105_000_000_000u64.into()],
1048            vec![102_000_000_000u64.into()],
1049        ]; // say, last 3 blocks
1050        let (base_fee, priority_fee) = eip1559_default_estimator(base_fee_per_gas, rewards.clone());
1051        assert_eq!(base_fee, base_fee_surged(base_fee_per_gas));
1052        assert_eq!(priority_fee, estimate_priority_fee(rewards.clone()));
1053
1054        // The median should be taken because none of the changes are big enough to ignore values.
1055        assert_eq!(estimate_priority_fee(rewards), 102_000_000_000u64.into());
1056
1057        // Ensure fee estimation doesn't panic when overflowing a u32. This had been a divide by
1058        // zero.
1059        let overflow = U256::from(u32::MAX) + 1;
1060        let rewards_overflow: Vec<Vec<U256>> = vec![vec![overflow], vec![overflow]];
1061        assert_eq!(estimate_priority_fee(rewards_overflow), overflow);
1062    }
1063}