From bb64adef131aa171be8da35cb13d68dc45d80dcf Mon Sep 17 00:00:00 2001 From: GnP Date: Mon, 21 Apr 2025 08:41:45 -0300 Subject: [PATCH 1/2] Add setting to cap the max price allowed for useroperations --- src/ethproto/aa_bundler.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/ethproto/aa_bundler.py b/src/ethproto/aa_bundler.py index 8a397a3..1d542f1 100644 --- a/src/ethproto/aa_bundler.py +++ b/src/ethproto/aa_bundler.py @@ -29,6 +29,7 @@ AA_BUNDLER_PRIORITY_GAS_PRICE_FACTOR = env.float("AA_BUNDLER_PRIORITY_GAS_PRICE_FACTOR", 1) AA_BUNDLER_BASE_GAS_PRICE_FACTOR = env.float("AA_BUNDLER_BASE_GAS_PRICE_FACTOR", 1) AA_BUNDLER_VERIFICATION_GAS_FACTOR = env.float("AA_BUNDLER_VERIFICATION_GAS_FACTOR", 1) +AA_BUNDLER_MAX_FEE_PER_GAS = env.int("AA_BUNDLER_MAX_FEE_PER_GAS", 200000000000) # 200 gwei AA_BUNDLER_STATE_OVERRIDES = env.json("AA_BUNDLER_STATE_OVERRIDES", default={}) @@ -329,6 +330,7 @@ def __init__( gas_limit_factor: float = AA_BUNDLER_GAS_LIMIT_FACTOR, priority_gas_price_factor: float = AA_BUNDLER_PRIORITY_GAS_PRICE_FACTOR, base_gas_price_factor: float = AA_BUNDLER_BASE_GAS_PRICE_FACTOR, + max_fee_per_gas: int = AA_BUNDLER_MAX_FEE_PER_GAS, executor_pk: HexBytes = AA_BUNDLER_EXECUTOR_PK, overrides: StateOverride = AA_BUNDLER_STATE_OVERRIDES, ): @@ -343,6 +345,7 @@ def __init__( self.priority_gas_price_factor = priority_gas_price_factor self.base_gas_price_factor = base_gas_price_factor self.executor_pk = executor_pk + self.max_fee_per_gas = max_fee_per_gas # stateOverrideSet mapping to use when calling eth_estimateUserOperationGas # https://docs.alchemy.com/reference/eth-estimateuseroperationgas @@ -406,10 +409,17 @@ def alchemy_gas_price(self): if "error" in resp: raise BundlerRevertError(resp["error"]["message"], response=resp) max_priority_fee_per_gas = int(int(resp["result"], 16) * self.priority_gas_price_factor) - max_fee_per_gas = max_priority_fee_per_gas + self.get_base_fee() + max_fee_per_gas = min(max_priority_fee_per_gas + self.get_base_fee(), self.max_fee_per_gas) return GasPrice(max_priority_fee_per_gas=max_priority_fee_per_gas, max_fee_per_gas=max_fee_per_gas) + def generic_gas_price(self): + base_fee = self.get_base_fee() + priority_fee = self.w3.eth.max_priority_fee + max_priority_fee_per_gas = int(priority_fee * self.priority_gas_price_factor) + max_fee_per_gas = min(max_priority_fee_per_gas + base_fee, self.max_fee_per_gas) + return GasPrice(max_priority_fee_per_gas=max_priority_fee_per_gas, max_fee_per_gas=max_fee_per_gas) + def build_user_operation(self, tx: Tx, retry_nonce=None) -> UserOperation: nonce_key, nonce = self.get_nonce_and_key(tx, fetch=retry_nonce is not None) # Consume the nonce, even if the userop may fail later @@ -422,16 +432,15 @@ def build_user_operation(self, tx: Tx, retry_nonce=None) -> UserOperation: if self.bundler_type == "alchemy": gas_price = self.alchemy_gas_price() - user_operation = user_operation.add_gas_price(gas_price) elif self.bundler_type == "generic": - # At the moment generic just prices the gas at 0 - pass + gas_price = self.generic_gas_price() else: warn(f"Unknown bundler_type: {self.bundler_type}") + gas_price = GasPrice(0, 0) - return user_operation + return user_operation.add_gas_price(gas_price) def send_transaction(self, tx: Tx, retry_nonce=None): user_operation = self.build_user_operation(tx, retry_nonce).sign( From 1088c5d5b0e7e8cb1f0a48fb09a2bef935bbec8c Mon Sep 17 00:00:00 2001 From: GnP Date: Mon, 21 Apr 2025 08:49:59 -0300 Subject: [PATCH 2/2] Add new parameter to rep --- src/ethproto/aa_bundler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ethproto/aa_bundler.py b/src/ethproto/aa_bundler.py index 1d542f1..3c2c99c 100644 --- a/src/ethproto/aa_bundler.py +++ b/src/ethproto/aa_bundler.py @@ -356,7 +356,7 @@ def __str__(self): f"Bundler(type={self.bundler_type}, entrypoint={self.entrypoint}, nonce_mode={self.nonce_mode}, " f"fixed_nonce_key={self.fixed_nonce_key}, verification_gas_factor={self.verification_gas_factor}, " f"gas_limit_factor={self.gas_limit_factor}, priority_gas_price_factor={self.priority_gas_price_factor}, " - f"base_gas_price_factor={self.base_gas_price_factor})" + f"base_gas_price_factor={self.base_gas_price_factor}, max_fee_per_gas={self.max_fee_per_gas})" ) def get_nonce_and_key(self, tx: Tx, fetch=False):