refactor(core): use non-async function ETH staking detection
What changed, and why it matters
This commit is a small internal code cleanup in Trezor's Ethereum transaction signing code. It changes a function that detects and handles Ethereum staking transactions from an 'async' (pause-able) style to a regular function that returns a confirmation task. There is no visible change in behavior, no bug fix, and no security-relevant change described by the vendor.
No security action needed. Treat as routine refactoring.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The diff refactors handle_staking() from an async function returning bool into get_staking_approver(), a synchronous function returning Coroutine[Any, Any, None] | None. The caller now awaits the returned coroutine explicitly. The logic paths, conditions, and helper calls (_handle_staking_tx_stake, _handle_staking_tx_unstake, _handle_staking_tx_claim) remain identical. No constants, validation, or control flow affecting security were modified.
Changed components
core/src/apps/ethereum/sign_tx.pyInspect captured patch +18 / −13
diff --git a/core/src/apps/ethereum/sign_tx.py b/core/src/apps/ethereum/sign_tx.py
index 508557af..ff27a51e 100644
--- a/core/src/apps/ethereum/sign_tx.py
+++ b/core/src/apps/ethereum/sign_tx.py
@@ -12,7 +12,7 @@ from .keychain import with_keychain_from_chain_id
if TYPE_CHECKING:
from buffer_types import AnyBytes
- from typing import Iterable
+ from typing import Any, Coroutine, Iterable
from trezor.messages import (
EthereumNetworkInfo,
@@ -182,8 +182,11 @@ async def confirm_tx_data(
REVOKE_AMOUNT = constants.SC_FUNC_APPROVE_REVOKE_AMOUNT
EIP_7702_TX_TYPE = constants.EIP_7702_TX_TYPE
- if await handle_staking(msg, defs.network, address_bytes, maximum_fee, fee_items):
- return
+ staking_approver = get_staking_approver(
+ msg, defs.network, address_bytes, maximum_fee, fee_items
+ )
+ if staking_approver is not None:
+ return await staking_approver
if tx_type == EIP_7702_TX_TYPE:
# we have already made sure that the address is a known address
@@ -286,34 +289,37 @@ async def confirm_tx_data(
)
-async def handle_staking(
+def get_staking_approver(
msg: MsgInSignTx,
network: EthereumNetworkInfo,
address_bytes: bytes,
maximum_fee: str,
fee_items: Iterable[StrPropertyType],
-) -> bool:
+) -> Coroutine[Any, Any, None] | None:
+ """
+ Returns a awaitable confirmation for ETH staking approval.
+
+ `None` is returned for non-staking related transactions.
+ """
data_reader = BufferReader(msg.data_initial_chunk)
if data_reader.remaining_count() < constants.SC_FUNC_SIG_BYTES:
- return False
+ return None
func_sig = data_reader.read_memoryview(constants.SC_FUNC_SIG_BYTES)
if address_bytes in constants.ADDRESSES_POOL:
if func_sig == constants.SC_FUNC_SIG_STAKE:
- await _handle_staking_tx_stake(
+ return _handle_staking_tx_stake(
data_reader, msg, network, address_bytes, maximum_fee, fee_items
)
- return True
if func_sig == constants.SC_FUNC_SIG_UNSTAKE:
- await _handle_staking_tx_unstake(
+ return _handle_staking_tx_unstake(
data_reader, msg, network, address_bytes, maximum_fee, fee_items
)
- return True
if address_bytes in constants.ADDRESSES_ACCOUNTING:
if func_sig == constants.SC_FUNC_SIG_CLAIM:
- await _handle_staking_tx_claim(
+ return _handle_staking_tx_claim(
data_reader,
msg,
address_bytes,
@@ -322,10 +328,9 @@ async def handle_staking(
network,
bool(msg.chunkify),
)
- return True
# data not corresponding to staking transaction
- return False
+ return None
async def _handle_known_contract_calls(
Why this scored 11/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.