Skip to content

Commit

Permalink
fix: correctly determine withdrawal params for withdrawalinitiated ev…
Browse files Browse the repository at this point in the history
…ents (#301)
  • Loading branch information
montekki authored Nov 14, 2023
1 parent e9649a8 commit 94d6ecd
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 23 deletions.
12 changes: 2 additions & 10 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ tokio = "1.34.0"
clap = "4.4.8"
tracing = "0.1"
tracing-subscriber = "0.3"
lru = "0.12.0"
sentry = { version = "0", default-features = false }
lazy_static = "1.4.0"
itertools = "0.11.0"
Expand Down
2 changes: 2 additions & 0 deletions bin/withdrawal-finalizer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ color-eyre = { workspace = true }
ethers = { workspace = true, default-features = false, features = ["ws", "rustls"] }
tokio = { workspace = true, features = ["full"] }
url = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
eyre = { workspace = true }
tokio-stream = { workspace = true }
envconfig = { workspace = true }
Expand Down
46 changes: 46 additions & 0 deletions bin/withdrawal-finalizer/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use std::str::FromStr;

use envconfig::Envconfig;
use ethers::types::Address;
use finalizer::{AddrList, TokenList};
use serde::{Deserialize, Serialize};
use url::Url;

/// Withdrawal finalizer configuration.
Expand Down Expand Up @@ -77,4 +80,47 @@ pub struct Config {

#[envconfig(from = "ENABLE_WITHDRAWAL_METERING")]
pub enable_withdrawal_metering: Option<bool>,

#[envconfig(from = "CUSTOM_TOKEN_ADDRESS_MAPPINGS")]
pub custom_token_address_mappings: Option<CustomTokenAddressMappings>,
}

#[derive(Deserialize, Serialize, Debug, Eq, PartialEq)]
pub struct CustomTokenAddressMapping {
pub l_1_addr: Address,
pub l_2_addr: Address,
}

impl FromStr for CustomTokenAddressMapping {
type Err = serde_json::Error;

fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
serde_json::from_str(s)
}
}

#[derive(Debug, Default, Serialize, Deserialize)]
pub struct CustomTokenAddressMappings(pub Vec<CustomTokenAddressMapping>);

impl FromStr for CustomTokenAddressMappings {
type Err = serde_json::Error;

fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
let res: CustomTokenAddressMappings = serde_json::from_str(s)?;

Ok(res)
}
}

impl Config {
/// Returns a mapping of tokens (L1, L2) addresses.
pub fn token_mappings(&self) -> Vec<(Address, Address)> {
self.custom_token_address_mappings
.as_ref()
.map(|f| &f.0)
.unwrap_or(&vec![])
.iter()
.map(|m| (m.l_1_addr, m.l_2_addr))
.collect()
}
}
1 change: 1 addition & 0 deletions bin/withdrawal-finalizer/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ async fn main() -> Result<()> {
tracing::info!("No sentry url configured");
}

client::add_predefined_token_addrs(config.token_mappings().as_ref()).await;
let stop_vise_exporter = run_vise_exporter()?;

// Successful reconnections do not reset the reconnection count trackers in the
Expand Down
1 change: 0 additions & 1 deletion client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ thiserror = { workspace = true }
chrono = { workspace = true, features = ["serde"] }
serde = { workspace = true }
vise = { workspace = true }
lru = { workspace = true }
ethers-log-decode = { workspace = true }
lazy_static = { workspace = true }
tokio = { workspace = true }
Expand Down
8 changes: 7 additions & 1 deletion client/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
use ethers::{
abi::EncodePackedError, contract::ContractError, prelude::Middleware, providers::ProviderError,
abi::{Address, EncodePackedError},
contract::ContractError,
prelude::Middleware,
providers::ProviderError,
types::H256,
};

Expand Down Expand Up @@ -44,6 +47,9 @@ pub enum Error {

#[error("Message not RLP bytes encoded: {0}")]
MessageNotRlpBytes(String),

#[error("L1 address of L2 token {0:?} is not known")]
L2TokenUnknown(Address),
}

impl<M: Middleware> From<ContractError<M>> for Error {
Expand Down
37 changes: 27 additions & 10 deletions client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
mod error;
mod metrics;

use std::num::NonZeroUsize;
use std::collections::HashMap;
use std::sync::Arc;

pub use error::{Error, Result};
Expand All @@ -28,7 +28,6 @@ use l1bridge::codegen::{FinalizeWithdrawalCall, IL1Bridge};
use l1messenger::codegen::L1MessageSentFilter;
use l2standard_token::codegen::{BridgeBurnFilter, L1AddressCall};
use lazy_static::lazy_static;
use lru::LruCache;
use tokio::sync::Mutex;
use withdrawal_finalizer::codegen::RequestFinalizeWithdrawal;
use zksync_contract::codegen::{FinalizeEthWithdrawalCall, IZkSync};
Expand Down Expand Up @@ -82,11 +81,22 @@ pub fn is_eth(address: Address) -> bool {
enum WithdrawalEvents {
BridgeBurn(BridgeBurnFilter),
Withdrawal(WithdrawalFilter),
WithdrawalInitiated(WithdrawalInitiatedFilter),
}

lazy_static! {
static ref TOKEN_ADDRS: Arc<Mutex<LruCache<Address, Address>>> =
Arc::new(Mutex::new(LruCache::new(NonZeroUsize::new(64).unwrap())));
static ref TOKEN_ADDRS: Arc<Mutex<HashMap<Address, Address>>> =
Arc::new(Mutex::new(HashMap::new()));
}

/// Adds configurable sets of tokens with known deployment addresses
pub async fn add_predefined_token_addrs(addrs: &[(Address, Address)]) {
println!("ADADAD {addrs:?}");
let mut addr_lock = TOKEN_ADDRS.lock().await;

for (addr_l1, addr_l2) in addrs {
addr_lock.insert(*addr_l2, *addr_l1);
}
}

impl WithdrawalParams {
Expand Down Expand Up @@ -339,6 +349,13 @@ impl<P: JsonRpcClient> ZksyncMiddleware for Provider<P> {
let withdrawal_event = WithdrawalEvents::decode_log(&raw_log)?;

let l2_to_l1_message_hash = match withdrawal_event {
WithdrawalEvents::WithdrawalInitiated(w) => {
let addr_lock = TOKEN_ADDRS.lock().await;
let l_1_token = addr_lock
.get(&w.l_2_token)
.ok_or(Error::L2TokenUnknown(w.l_2_token))?;
get_l1_bridge_burn_message_keccak(w.amount, w.l_1_receiver, *l_1_token)?
}
WithdrawalEvents::BridgeBurn(b) => {
let mut addr_lock = TOKEN_ADDRS.lock().await;

Expand All @@ -357,7 +374,7 @@ impl<P: JsonRpcClient> ZksyncMiddleware for Provider<P> {

let l1_address = Address::decode(self.call(&call, None).await?)?;

addr_lock.put(withdrawal_log.address, l1_address);
addr_lock.insert(withdrawal_log.address, l1_address);

l1_address
};
Expand All @@ -380,7 +397,7 @@ impl<P: JsonRpcClient> ZksyncMiddleware for Provider<P> {

let l1_receiver = withdrawal_initiated_event.l_1_receiver;

get_l1_bridge_burn_message_keccak(&b, l1_receiver, l1_address)?
get_l1_bridge_burn_message_keccak(b.amount, l1_receiver, l1_address)?
}
WithdrawalEvents::Withdrawal(w) => get_l1_withdraw_message_keccak(&w)?,
};
Expand Down Expand Up @@ -562,15 +579,15 @@ where
}

fn get_l1_bridge_burn_message_keccak(
burn: &BridgeBurnFilter,
amount: U256,
l1_receiver: Address,
l1_token: Address,
) -> Result<H256> {
let message = ethers::abi::encode_packed(&[
Token::FixedBytes(FinalizeWithdrawalCall::selector().to_vec()),
Token::Address(l1_receiver),
Token::Address(l1_token),
Token::Bytes(burn.amount.encode()),
Token::Bytes(amount.encode()),
])?;
Ok(ethers::utils::keccak256(message).into())
}
Expand Down Expand Up @@ -605,7 +622,7 @@ mod tests {
};

let a = super::get_l1_bridge_burn_message_keccak(
&bridge_burn,
bridge_burn.amount,
// withdraws to the same account on L1, so can take this value.
bridge_burn.account,
dai_l1_addr,
Expand Down Expand Up @@ -656,7 +673,7 @@ mod tests {
};

let a = super::get_l1_bridge_burn_message_keccak(
&bridge_burn,
bridge_burn.amount,
"d1ced2fBDFa24daa9920D37237ca2D4d5616a6e2".parse().unwrap(),
dai_l1_addr,
)
Expand Down

0 comments on commit 94d6ecd

Please sign in to comment.