From 39008d863f0ab4e70a1e6e9ec64a0829286ab119 Mon Sep 17 00:00:00 2001
From: Ivan Schasny <31857042+ischasny@users.noreply.github.com>
Date: Tue, 10 Sep 2024 14:19:01 +0100
Subject: [PATCH] fix: eip712 rlp encoding fix (#132)
* fix: eip712 rlp encoding fix
* review fixes
---
src/eip712/meta.rs | 14 +++----
src/eip712/paymaster_params.rs | 17 ++++-----
src/eip712/transaction.rs | 9 ++---
src/eip712/transaction_request.rs | 63 +++++++++++--------------------
src/zks_provider/mod.rs | 5 ++-
5 files changed, 42 insertions(+), 66 deletions(-)
diff --git a/src/eip712/meta.rs b/src/eip712/meta.rs
index a17ac9f..f366654 100644
--- a/src/eip712/meta.rs
+++ b/src/eip712/meta.rs
@@ -68,17 +68,15 @@ impl Encodable for Eip712Meta {
// 12
stream.append(&self.gas_per_pubdata);
// 13
- if !self.factory_deps.is_empty() {
- stream.begin_list(self.factory_deps.len());
- for dep in self.factory_deps.iter() {
- stream.append(dep);
- }
- } else {
- stream.begin_list(0);
+ stream.begin_list(self.factory_deps.len());
+ for dep in self.factory_deps.iter() {
+ stream.append(dep);
}
// 14
rlp_append_option(stream, self.custom_signature.clone().map(|v| v.to_vec()));
// 15
- self.paymaster_params.rlp_append(stream);
+ if let Some(paymaster_params) = self.paymaster_params.clone() {
+ paymaster_params.rlp_append(stream);
+ }
}
}
diff --git a/src/eip712/paymaster_params.rs b/src/eip712/paymaster_params.rs
index fe8ed78..8dcd455 100644
--- a/src/eip712/paymaster_params.rs
+++ b/src/eip712/paymaster_params.rs
@@ -1,6 +1,5 @@
-use super::rlp_append_option;
use ethers::{
- types::{Address, Bytes},
+ types::Address,
utils::rlp::Encodable,
};
use serde::Serialize;
@@ -8,18 +7,18 @@ use serde::Serialize;
#[derive(Serialize, serde::Deserialize, Clone, Debug, Default)]
#[serde(rename_all(serialize = "camelCase", deserialize = "camelCase"))]
pub struct PaymasterParams {
- pub paymaster: Option
,
- pub paymaster_input: Option,
+ pub paymaster: Address,
+ pub paymaster_input: Vec,
}
impl PaymasterParams {
pub fn paymaster(mut self, paymaster: Address) -> Self {
- self.paymaster = Some(paymaster);
+ self.paymaster = paymaster;
self
}
- pub fn paymaster_input(mut self, paymaster_input: Bytes) -> Self {
- self.paymaster_input = Some(paymaster_input);
+ pub fn paymaster_input(mut self, paymaster_input: Vec) -> Self {
+ self.paymaster_input = paymaster_input;
self
}
}
@@ -27,7 +26,7 @@ impl PaymasterParams {
impl Encodable for PaymasterParams {
fn rlp_append(&self, stream: &mut ethers::utils::rlp::RlpStream) {
stream.begin_list(2);
- rlp_append_option(stream, self.paymaster);
- rlp_append_option(stream, self.paymaster_input.clone().map(|v| v.to_vec()));
+ stream.append(&self.paymaster);
+ stream.append(&self.paymaster_input.clone());
}
}
diff --git a/src/eip712/transaction.rs b/src/eip712/transaction.rs
index a6427fb..1061399 100644
--- a/src/eip712/transaction.rs
+++ b/src/eip712/transaction.rs
@@ -290,12 +290,9 @@ impl TryFrom for Eip712Transaction {
.chain_id(tx.chain_id);
if let Some(paymaster_params) = tx.custom_data.paymaster_params {
- if let Some(paymaster) = paymaster_params.paymaster {
- eip712_transaction = eip712_transaction.paymaster(paymaster)
- }
- if let Some(paymaster_input) = paymaster_params.paymaster_input {
- eip712_transaction = eip712_transaction.paymaster_input(paymaster_input)
- }
+ eip712_transaction = eip712_transaction
+ .paymaster(paymaster_params.paymaster)
+ .paymaster_input(paymaster_params.paymaster_input);
}
if let Some(gas_limit) = tx.gas_limit {
diff --git a/src/eip712/transaction_request.rs b/src/eip712/transaction_request.rs
index ddefc2e..7a1b03e 100644
--- a/src/eip712/transaction_request.rs
+++ b/src/eip712/transaction_request.rs
@@ -173,48 +173,29 @@ impl Eip712TransactionRequest {
}
pub fn rlp(&self, signature: Option) -> Result {
- let mut stream = RlpStream::new();
- stream.begin_unbounded_list();
-
- // 0
- stream.append(&self.nonce);
- // 1
- stream.append(&self.max_priority_fee_per_gas);
- // 2
- rlp_append_option(&mut stream, self.max_fee_per_gas);
- // 3 (supped to be gas)
- rlp_append_option(&mut stream, self.gas_limit);
- // 4
- stream.append(&self.to);
- // 5
- stream.append(&self.value);
- // 6
- stream.append(&self.data.0);
- // 7
- stream.append(&self.chain_id);
- // 8
- stream.append(&"");
- // 9
- stream.append(&"");
- // 10
- stream.append(&self.chain_id);
- // 11
- stream.append(&self.from);
- // 12, 13, 14, 15
- if self.custom_data.custom_signature.clone().is_some() {
- self.custom_data.rlp_append(&mut stream);
- } else if let Some(signature) = signature {
- let tx = self.clone().custom_data(
- self.clone()
- .custom_data
- .custom_signature(signature.to_vec()),
- );
- tx.custom_data.rlp_append(&mut stream);
- } else {
- return Err(Eip712Error::Message("No signature provided".to_owned()));
+ let mut rlp = RlpStream::new();
+ rlp.begin_unbounded_list();
+ rlp.append(&self.nonce);
+ rlp.append(&self.max_priority_fee_per_gas);
+ rlp.append(&self.gas_price);
+ rlp_append_option(&mut rlp, self.gas_limit);
+ rlp.append(&self.to);
+ rlp.append(&self.value);
+ rlp.append(&self.data.0);
+ if let Some(sig) = signature {
+ rlp.append(&sig.v);
+ // Convert to big-endian bytes (32 bytes in total)
+ let mut bytes = [0_u8; 32]; // U256 is 32 bytes
+ sig.r.to_big_endian(&mut bytes);
+ rlp.append(&bytes.as_slice());
+ sig.s.to_big_endian(&mut bytes);
+ rlp.append(&bytes.as_slice());
}
- stream.finalize_unbounded_list();
- Ok(stream.out().freeze().into())
+ rlp.append(&self.chain_id);
+ rlp.append(&self.from);
+ self.custom_data.rlp_append(&mut rlp);
+ rlp.finalize_unbounded_list();
+ Ok(rlp.out().freeze().into())
}
}
diff --git a/src/zks_provider/mod.rs b/src/zks_provider/mod.rs
index 5a95f60..ffc23ff 100644
--- a/src/zks_provider/mod.rs
+++ b/src/zks_provider/mod.rs
@@ -704,12 +704,13 @@ impl ZKSProvider for Provider {
ProviderError::CustomError("error on send_transaction_eip712".to_owned())
})?;
+ let gas_price = self.get_gas_price().await?;
request = request
.from(wallet.address())
.chain_id(wallet.chain_id())
.nonce(self.get_transaction_count(wallet.address(), None).await?)
- .gas_price(self.get_gas_price().await?)
- .max_fee_per_gas(self.get_gas_price().await?);
+ .gas_price(gas_price)
+ .max_fee_per_gas(gas_price);
let custom_data = request.clone().custom_data;
let fee = self.estimate_fee(request.clone()).await?;